home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / workbench werkzeuge / uhren & terminkalender / time / tolleuhr / tolleuhr_c / source / tolleuhr.c < prev    next >
C/C++ Source or Header  |  1996-04-07  |  74KB  |  2,537 lines

  1. #define VERSION "1.3 (17.11.95)"
  2. /***************************************************************************
  3. *                                  *                                       *
  4. * Programm: TolleUhr               * Version: s.o.                         *
  5. *                                  *                                       *
  6. ****************************************************************************
  7. *                                                                          *
  8. * Dieses Programm ist Public-Domain, d.h. wer immer Lust dazu hat, darf    *
  9. * dieses Programm kopieren, umschreiben, usw., vorausgesetzt:              *
  10. *                                                                          *
  11. * 1. Die Autorenliste bleibt voll erhalten. (auch in About-Requestern)     *
  12. * 2. Wer etwas am Programm verbricht, muß sich auch dazuschreiben.         *
  13. *                                                                          *
  14. * Es wird keine Haftung für Schäden irgendwelcher Art übernommen.          *
  15. *                                                                          *
  16. * Autoren: Matthias Fleischer  Adlerstraße 30 7302 Ostfildern 2            *
  17. *          (fleischr@izfm.uni-stuttgart.de)                                *
  18. *          .                                                               *
  19. *          .(Auf Paul, schaff was !)                                       *
  20. *                                                                          *
  21. *          Gunther Nikl  Ziegendorfer Chaussee 96 19370 Parchim            *
  22. *          (gnikl@informatik.uni-rostock.de)                               *
  23. *                                                                          *
  24. ***************************************************************************/
  25.  
  26. /***************************************************************************/
  27. /*                                                                         */
  28. /* includes                                                                */
  29. /*                                                                         */
  30. /***************************************************************************/
  31.  
  32. #include <exec/types.h>
  33.  
  34. #ifndef CONST
  35. #define CONST const
  36. #endif
  37. #ifndef INLINE
  38. #define INLINE inline
  39. #endif
  40.  
  41. #include <dos/dos.h>
  42. #include <dos/rdargs.h>
  43. #include <exec/memory.h>
  44. #include <devices/audio.h>
  45. #include <devices/timer.h>
  46. #include <hardware/cia.h>
  47. #include <graphics/gfxmacros.h>
  48. #include <intuition/intuition.h>
  49. #include <intuition/gadgetclass.h>
  50. #include <datatypes/pictureclass.h>
  51. #include <libraries/gadtools.h>
  52. #include <workbench/startup.h>
  53. #include <workbench/workbench.h>
  54. #include <clib/alib_protos.h>
  55. #include <clib/macros.h>
  56.  
  57. /*
  58. ** structure definitions now!
  59. */
  60.  
  61. struct gInfo {
  62.   WORD  left,top,width,height;
  63.   UWORD textnr,kind;
  64. };
  65.  
  66. struct wInfo {
  67.   UWORD        idcmp,textnr,gadcnt;
  68.   struct gInfo gi[1];
  69. };
  70.  
  71. struct WinGad {
  72.   struct Window *Win;
  73.   struct Gadget *Gad;
  74. };
  75.  
  76. struct BackFillInfo {
  77.   STRPTR               PictureName;
  78.   Object              *PictureObject;
  79.   struct BitMapHeader *BitMapHeader;
  80.   struct BitMap       *BitMap;
  81. };
  82.  
  83. /*
  84. ** sizeof(struct Globals) _MUST_ be a multiple of 4!
  85. */
  86.  
  87. struct Globals {
  88.  
  89.   /*** library stuff ***/
  90.  
  91.   struct ExecBase      *SysBase;
  92.   struct DosLibrary    *DOSBase;
  93.   struct IntuitionBase *IntuitionBase;
  94.   struct GfxBase       *GfxBase;
  95.   struct Library       *GadtoolsBase,
  96.                        *IconBase,
  97.                        *DataTypesBase;
  98.   struct LocaleBase    *LocaleBase;
  99.   struct Catalog       *Catalog;
  100.  
  101.   /*** misc stuff ***/
  102.  
  103.   struct Process       *OurTask;
  104.   struct WBStartup     *WbMsg;
  105.   BPTR                  OldLock;
  106.   STRPTR                NameBuf;
  107.   LONG                  OldPri;
  108.  
  109.   /*** device stuff ***/
  110.  
  111.   struct MsgPort       *WindowPort;
  112.   struct MsgPort       *TimerPort;
  113.   struct timerequest   *TimerIO;
  114.   struct MsgPort       *AudioPort;
  115.   struct IOAudio       *AudioIO[2];
  116.   APTR                  WaveForm;
  117.  
  118.   /*** graphic stuff ***/
  119.  
  120.   APTR                  VisualInfo;
  121.   struct Menu          *Menus;
  122.   struct Window        *MainWin;
  123.   struct RastPort      *RPort1;
  124.   struct WinGad         ColorWin,
  125.                         AlarmWin;
  126.   struct Window        *AboutReq;
  127.  
  128.   /*** common variables ***/
  129.  
  130.   LONG                  Left,
  131.                         Top,
  132.                         Width,
  133.                         Height,
  134.                         BoLeft,
  135.                         BoTop,
  136.                         Width2,
  137.                         Height2,
  138.                         ReDrawx1,
  139.                         ReDrawy1,
  140.                         ReDrawx2,
  141.                         ReDrawy2,
  142.                         xMask,
  143.                         yMask;
  144.   PLANEPTR              Buf;
  145.   UWORD                *PlayTune;
  146.   UBYTE                *Color;
  147.   LONG                  Std,
  148.                         Min,
  149.                         Sec,
  150.                         AlStd,
  151.                         AlMin,
  152.                         St,
  153.                         Mi,
  154.                         xOffset,
  155.                         yOffset;
  156.   WORD                  GadSize;
  157.  
  158.   /*** flags ***/
  159.  
  160.   BYTE                  TimerOpen,
  161.                         TimerSent,
  162.                         AudioOpen,
  163.                         AudioSent[2],
  164.                         SoundOn,
  165.                         xDouble,
  166.                         yDouble,
  167.                         ChangedDir,
  168.                         ChangedPri,
  169.                         Active,
  170.                         Alarm,
  171.                         Filter,
  172.                         HiRes,
  173.                         Interlace,
  174.                         SmartHour,
  175.                         EndAll;
  176.   UBYTE                 Seconds,
  177.                         Oval,
  178.                         Show,
  179.                         HandType,
  180.                         HandWidth,
  181.                         Shadow,
  182.                         BorderCount,
  183.                         Chime,
  184.                         UseImage,
  185.                         CloseGad,
  186.                         NoRemap,
  187.                         RequestNr,
  188.                         bPad;
  189.  
  190.   /*** structures ***/
  191.  
  192.   struct BackFillInfo   BFInfo;
  193.   struct WBArg          ProgArg;
  194.   UBYTE                 Pens[16],
  195.                         Must[4];
  196.   struct NewWindow      NewWindowBuf;
  197.   struct Gadget         GadgetBuf[4];
  198.   struct RastPort       RPort2;
  199.   struct BitMap         BitMap1;
  200.   struct TmpRas         TempRas;
  201.   struct AreaInfo       AreaInfo;
  202.   UWORD                 Table[14],
  203.                         Muster[8][2];
  204.   struct NewGadget      NewGad;
  205.   UWORD                 wPad;
  206.   struct EasyStruct     EasyBuf;
  207. };
  208.  
  209. #define PUB_SCREEN (gb->NewWindowBuf.Screen)
  210.  
  211. /*
  212. ** ptr to the `global' data space (will be on the stack :-)
  213. */
  214.  
  215. register struct Globals *gb asm("a4");
  216.  
  217. /*
  218. ** redirect library bases to the `global' data space
  219. */
  220.  
  221. #define BASE_NAME gb->LocaleBase
  222. #include <proto/locale.h>
  223. #undef BASE_NAME
  224.  
  225. #define BASE_NAME gb->DataTypesBase
  226. #include <proto/datatypes.h>
  227. #undef BASE_NAME
  228.  
  229. #define BASE_NAME gb->IntuitionBase
  230. #include <proto/intuition.h>
  231. #undef BASE_NAME
  232.  
  233. #define BASE_NAME gb->GadtoolsBase
  234. #include <proto/gadtools.h>
  235. #undef BASE_NAME
  236.  
  237. #define BASE_NAME gb->GfxBase
  238. #include <proto/graphics.h>
  239. #undef BASE_NAME
  240.  
  241. #define BASE_NAME gb->IconBase
  242. #include <proto/icon.h>
  243. #undef BASE_NAME
  244.  
  245. #define BASE_NAME gb->SysBase
  246. #include <proto/exec.h>
  247. #undef BASE_NAME
  248.  
  249. #define BASE_NAME gb->DOSBase
  250. #include <proto/dos.h>
  251. #undef BASE_NAME
  252.  
  253. #include <proto/alib.h>
  254.  
  255. /*
  256. ** strcpy() && strlen()
  257. */
  258.  
  259. #include <string.h>
  260.  
  261. /*
  262. ** locale string numbers
  263. */
  264.  
  265. #include "tolleuhr_locale.h"
  266.  
  267. /***************************************************************************/
  268. /*                                                                         */
  269. /* prototypes                                                              */
  270. /*                                                                         */
  271. /***************************************************************************/
  272.  
  273. LONG OpenMainWindow();
  274. VOID LoadImage();
  275. LONG InitClock();
  276. LONG GetArguments();
  277. VOID MergeToolTypes();
  278. VOID ParseArgs(STRPTR,LONG);
  279. VOID ReadStr(UBYTE *,UBYTE *,UBYTE *,LONG);
  280. LONG XtoD(LONG);
  281. LONG OpenDevs();
  282. LONG OpenLibs();
  283. VOID Main();
  284. VOID CloseLibs();
  285. VOID CloseDevs();
  286. VOID NewSize1();
  287. VOID CloseAboutReq();
  288. VOID CloseGfx();
  289. VOID FreeWindow(struct WinGad *);
  290. VOID CloseWindowSafely(struct Window *);
  291. VOID CheckAboutReq();
  292. VOID CheckWindows();
  293. VOID HandleMenus(ULONG);
  294. LONG NewSize2();
  295. ULONG NextTick();
  296. VOID Rahmen();
  297. VOID ZifferBlatt();
  298. VOID Zeiger(ULONG,LONG,LONG,LONG,LONG);
  299. VOID Zeichnen();
  300. VOID SetPattern();
  301. VOID SaveSettings();
  302. STRPTR SetToolType(STRPTR,STRPTR,LONG,...);
  303. STRPTR GetToolType(LONG);
  304. STRPTR SetStr(STRPTR,STRPTR,LONG);
  305. LONG DtoX(LONG);
  306. VOID TestIfAlarm();
  307. VOID StartTune(CONST UWORD *);
  308. VOID PlayNote();
  309. VOID EndTune();
  310. VOID CreateRequest(struct WinGad *,struct wInfo *,struct TagItem **);
  311. struct Window *OpenWindowShared(struct NewWindow *,CONST struct TagItem *,ULONG);
  312. STRPTR GetCatalogString(LONG);
  313. VOID CopyTiledBitMap(struct BitMap *,LONG,LONG,struct BitMap *,LONG,LONG);
  314.  
  315. /*
  316. ** replacements
  317. */
  318.  
  319. Object *new_dt_object(APTR name, ULONG, ...);
  320. ULONG get_dt_attrs(Object *, ULONG, ...);
  321. LONG blt_bitmap(struct BitMap *,LONG,LONG,struct BitMap *,LONG,LONG,LONG,LONG,ULONG,ULONG,PLANEPTR);
  322.  
  323. /***************************************************************************/
  324. /*                                                                         */
  325. /* `global' defines                                                        */
  326. /*                                                                         */
  327. /***************************************************************************/
  328.  
  329. #define GB_GADCOUNT (sizeof(gb->GadgetBuf)/sizeof(struct Gadget))
  330.  
  331. #define ciaa (*((struct CIA*)0xbfe001L))
  332.  
  333. /***************************************************************************/
  334. /*                                                                         */
  335. /* memory clear function (!!! caution: size _MUST_ be a multiple of 4!!!)  */
  336. /*                                                                         */
  337. /***************************************************************************/
  338.  
  339. STATIC INLINE VOID MEMZEROL(VOID *mem,ULONG size)
  340. { ULONG *p;
  341.   WORD s;
  342.  
  343.   for(p=(ULONG *)mem,s=(size/sizeof(ULONG))-1; s>=0; *p++=NULL,s--);
  344. }
  345.  
  346. /***************************************************************************/
  347. /*                                                                         */
  348. /* implementation                                                          */
  349. /*                                                                         */
  350. /***************************************************************************/
  351.  
  352. LONG TolleUhr()
  353. { struct Globals globals;
  354.  
  355.   MEMZEROL(&globals,sizeof(struct Globals)); gb = &globals;
  356.  
  357.   gb->SysBase = *(struct ExecBase **)4L;
  358.  
  359.   Main();
  360.  
  361.   return 0;
  362. }
  363.  
  364. /***************************************************************************/
  365. /*                                                                         */
  366. /* version string                                                          */
  367. /*                                                                         */
  368. /***************************************************************************/
  369.  
  370. CONST UBYTE Version[] = "$VER: TolleUhr "VERSION" by M.Fleischer and G.Nikl in 1993/95";
  371.  
  372. #define PROGNAME ((UBYTE *)(&Version[6]))
  373.  
  374. /***************************************************************************/
  375. /*                                                                         */
  376. /* open clock window                                                       */
  377. /*                                                                         */
  378. /***************************************************************************/
  379.  
  380. #define MAINIDCMP (IDCMP_NEWSIZE | IDCMP_REFRESHWINDOW | IDCMP_MENUPICK | \
  381.                    IDCMP_CLOSEWINDOW | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW)
  382.  
  383. CONST struct TagItem WindowTags[] = {
  384.   { WA_InnerWidth , 148 },
  385.   { WA_InnerHeight,  72 },
  386.   { WA_AutoAdjust ,TRUE },
  387.   { TAG_DONE      ,NULL }
  388. };
  389.  
  390. LONG OpenMainWindow()
  391. {
  392.   struct NewWindow *nw;
  393.   struct Window *win;
  394.   LONG ret;
  395.  
  396.   nw = &gb->NewWindowBuf;
  397.  
  398.   nw->LeftEdge    = gb->Left;
  399.   nw->TopEdge     = gb->Top;
  400.   nw->Width       = gb->Width;
  401.   nw->Height      = gb->Height;
  402.   nw->BlockPen    = 1;
  403.   nw->Flags       = WFLG_SIMPLE_REFRESH | WFLG_BORDERLESS | WFLG_NEWLOOKMENUS;
  404.   nw->FirstGadget = &gb->GadgetBuf[0];
  405.   nw->MinWidth    = 10;
  406.   nw->MinHeight   = 10;
  407.   nw->MaxWidth    = 65535;
  408.   nw->MaxHeight   = 65535;
  409.   nw->Type        = PUBLICSCREEN;
  410.  
  411.   ret = 0;
  412.  
  413.   if ((gb->MainWin=(win=OpenWindowShared(nw,&WindowTags[2],MAINIDCMP))) != NULL)
  414.   {
  415.     gb->RPort1 = win->RPort;
  416.     SetWindowTitles(win,(UBYTE *)-1L,PROGNAME);
  417.     SetMenuStrip(win,gb->Menus);
  418.     if (!gb->BFInfo.BitMap || gb->UseImage)
  419.       OffMenu(win,(gb->UseImage ? FULLMENUNUM(3,NOITEM,NOSUB) : FULLMENUNUM(1,8,NOSUB)));
  420.     SetAPen(gb->RPort1,gb->Pens[0]);
  421.     if (!NewSize2())
  422.     {
  423.       NextTick();
  424.       Rahmen();
  425.       ZifferBlatt();
  426.       Zeichnen();
  427.       ret = 1;
  428.     }
  429.   }
  430.  
  431.   return ret;
  432. }
  433.  
  434. /***************************************************************************/
  435. /*                                                                         */
  436. /* load background image via datatypes                                     */
  437. /*                                                                         */
  438. /***************************************************************************/
  439.  
  440. CONST struct TagItem PicTags[] = {
  441.   { DTA_GroupID          ,GID_PICTURE     },
  442.   { PDTA_FreeSourceBitMap,TRUE            },
  443.   { OBP_Precision        ,PRECISION_IMAGE },
  444.   { TAG_DONE             ,NULL            }
  445. };
  446.  
  447. VOID LoadImage()
  448. { STRPTR name;
  449.   Object *obj;
  450.  
  451.   if (gb->DataTypesBase)
  452.     if ((name=gb->BFInfo.PictureName) != NULL)
  453.     {
  454.       gb->BFInfo.PictureObject = obj =
  455.         new_dt_object(name,
  456.                       PDTA_Screen,PUB_SCREEN,
  457.                       PDTA_Remap ,(gb->NoRemap ? FALSE : TRUE),
  458.                       TAG_MORE   ,PicTags);
  459.       if (obj != NULL)
  460.         if (DoMethod(obj,DTM_PROCLAYOUT,NULL,1))
  461.           get_dt_attrs(obj,
  462.                        PDTA_BitMapHeader,&gb->BFInfo.BitMapHeader,
  463.                        PDTA_DestBitMap  ,&gb->BFInfo.BitMap,
  464.                        TAG_DONE);
  465.     }
  466. }
  467.  
  468. /***************************************************************************/
  469. /*                                                                         */
  470. /* initialize all graphics                                                 */
  471. /*                                                                         */
  472. /***************************************************************************/
  473.  
  474. CONST UBYTE gadgetInfo[] = {
  475.   GADGHNONE                     ,GTYP_CLOSE,
  476.   GADGHNONE|GRELRIGHT           ,GTYP_WDEPTH,
  477.   GADGHNONE|GRELRIGHT|GRELBOTTOM,GTYP_SIZING,
  478.   GADGHNONE|GRELWIDTH|GRELHEIGHT,GTYP_WDRAGGING
  479. };
  480.  
  481. enum {
  482.   MENU_PROJECT=0,
  483.    MENU_PROJECT_ABOUT,
  484.    MENU_PROJECT_QUIT,
  485.   MENU_SETTINGS,
  486.    MENU_SETTINGS_SECONDS,
  487.    MENU_SETTINGS_OVAL,
  488.    MENU_SETTINGS_SHOW,
  489.     MENU_SETTINGS_SHOW_MINUTES,
  490.     MENU_SETTINGS_SHOW_HOURS,
  491.     MENU_SETTINGS_SHOW_QUARTER,
  492.     MENU_SETTINGS_SHOW_ONE,
  493.     MENU_SETTINGS_SHOW_NONE,
  494.    MENU_SETTINGS_HANDS,
  495.     MENU_SETTINGS_HANDS_LINE,
  496.     MENU_SETTINGS_HANDS_TRIANGLE,
  497.     MENU_SETTINGS_HANDS_RHOMBUS,
  498.     MENU_SETTINGS_HANDS_RECTANGLE,
  499.     MENU_SETTINGS_HANDS_BARLABEL,
  500.     MENU_SETTINGS_HANDS_VERYTHIN,
  501.     MENU_SETTINGS_HANDS_THIN,
  502.     MENU_SETTINGS_HANDS_NORMAL,
  503.     MENU_SETTINGS_HANDS_THICK,
  504.     MENU_SETTINGS_HANDS_VERYTHICK,
  505.    MENU_SETTINGS_SHADOW,
  506.    MENU_SETTINGS_BORDER,
  507.     MENU_SETTINGS_BORDER_NONE,
  508.     MENU_SETTINGS_BORDER_SINGLE,
  509.     MENU_SETTINGS_BORDER_DOUBLE,
  510.     MENU_SETTINGS_BORDER_BARLABEL,
  511.     MENU_SETTINGS_BORDER_HIRES,
  512.     MENU_SETTINGS_BORDER_INTERLACE,
  513.    MENU_SETTINGS_CHIME,
  514.     MENU_SETTINGS_CHIME_NONE,
  515.     MENU_SETTINGS_CHIME_HOURS,
  516.     MENU_SETTINGS_CHIME_QUARTER,
  517.     MENU_SETTINGS_CHIME_BARLABEL,
  518.     MENU_SETTINGS_CHIME_SMART,
  519.    MENU_SETTINGS_ALARM,
  520.     MENU_SETTINGS_ALARM_SET,
  521.     MENU_SETTINGS_ALARM_ON,
  522.    MENU_SETTINGS_USEIMAGE,
  523.    MENU_SETTINGS_CLOSEGAD,
  524.    MENU_SETTINGS_BARLABEL,
  525.    MENU_SETTINGS_SAVE,
  526.   MENU_COLORS,
  527.    MENU_COLORS_SECONDS,
  528.    MENU_COLORS_MINAPEN,
  529.    MENU_COLORS_MINOPEN,
  530.    MENU_COLORS_HOURAPEN,
  531.    MENU_COLORS_HOUROPEN,
  532.    MENU_COLORS_SHADOW,
  533.    MENU_COLORS_STR12,
  534.    MENU_COLORS_QUARTER,
  535.    MENU_COLORS_HOURS,
  536.    MENU_COLORS_MINUTES,
  537.    MENU_COLORS_BORDER0,
  538.    MENU_COLORS_BORDER1,
  539.    MENU_COLORS_BORDER2,
  540.    MENU_COLORS_BORDER3,
  541.   MENU_PATTERN,
  542.    MENU_PATTERN_COLOR0,
  543.    MENU_PATTERN_COLOR1,
  544.    MENU_PATTERN_COLOR2,
  545.    MENU_PATTERN_COLOR3
  546. };
  547.  
  548. CONST UBYTE MenuInfo[] = {
  549.   NM_TITLE,MSG_PROJECT,0,0,
  550.    NM_ITEM,MSG_ABOUT,0,0,
  551.    NM_ITEM,MSG_QUIT,0,0,
  552.   NM_TITLE,MSG_SETTINGS,0,0,
  553.    NM_ITEM,MSG_SECONDS,CHECKIT|MENUTOGGLE,0,
  554.    NM_ITEM,MSG_OVAL,CHECKIT|MENUTOGGLE,0,
  555.    NM_ITEM,MSG_SHOW,0,0,
  556.     NM_SUB,MSG_MINUTES,CHECKIT,2|4|8|16,
  557.     NM_SUB,MSG_HOURS,CHECKIT,1|4|8|16,
  558.     NM_SUB,MSG_QUARTER,CHECKIT,1|2|8|16,
  559.     NM_SUB,MSG_ONE,CHECKIT,1|2|4|16,
  560.     NM_SUB,MSG_NONE,CHECKIT,1|2|4|8,
  561.    NM_ITEM,MSG_HANDS,0,0,
  562.     NM_SUB,MSG_LINE,CHECKIT,2|4|8,
  563.     NM_SUB,MSG_TRIANGLE,CHECKIT,1|4|8,
  564.     NM_SUB,MSG_RHOMBUS,CHECKIT,1|2|8,
  565.     NM_SUB,MSG_RECTANGLE,CHECKIT,1|2|4,
  566.     NM_SUB,(UBYTE)NM_BARLABEL,0,0,
  567.     NM_SUB,MSG_VERYTHIN,CHECKIT,128+(2|4|8|16),
  568.     NM_SUB,MSG_THIN,CHECKIT,128+(1|4|8|16),
  569.     NM_SUB,MSG_NORMAL,CHECKIT,128+(1|2|8|16),
  570.     NM_SUB,MSG_THICK,CHECKIT,128+(1|2|4|16),
  571.     NM_SUB,MSG_VERYTHICK,CHECKIT,128+(1|2|4|8),
  572.    NM_ITEM,MSG_SHADOW,CHECKIT|MENUTOGGLE,0,
  573.    NM_ITEM,MSG_BORDER,0,0,
  574.     NM_SUB,MSG_NONE,CHECKIT,2|4,
  575.     NM_SUB,MSG_SINGLE,CHECKIT,1|4,
  576.     NM_SUB,MSG_DOUBLE,CHECKIT,1|2,
  577.     NM_SUB,(UBYTE)NM_BARLABEL,0,0,
  578.     NM_SUB,MSG_HIRES,CHECKIT|MENUTOGGLE,0,
  579.     NM_SUB,MSG_INTERLACE,CHECKIT|MENUTOGGLE,0,
  580.    NM_ITEM,MSG_CHIME,0,0,
  581.     NM_SUB,MSG_NONE,CHECKIT,2|4,
  582.     NM_SUB,MSG_HOURS,CHECKIT,1|4,
  583.     NM_SUB,MSG_QUARTER,CHECKIT,1|2,
  584.     NM_SUB,(UBYTE)NM_BARLABEL,0,0,
  585.     NM_SUB,MSG_SMART,CHECKIT|MENUTOGGLE,0,
  586.    NM_ITEM,MSG_ALARM,0,0,
  587.     NM_SUB,MSG_SET,0,0,
  588.     NM_SUB,MSG_ON,CHECKIT|MENUTOGGLE,0,
  589.    NM_ITEM,MSG_USEIMAGE,CHECKIT|MENUTOGGLE,0,
  590.    NM_ITEM,MSG_CLOSEGAD,CHECKIT|MENUTOGGLE,0,
  591.    NM_ITEM,(UBYTE)NM_BARLABEL,0,0,
  592.    NM_ITEM,MSG_SAVESETTINGS,0,0,
  593.   NM_TITLE,MSG_COLORS,0,0,
  594.    NM_ITEM,MSG_SECONDS,0,0,
  595.    NM_ITEM,MSG_MINAPEN,0,0,
  596.    NM_ITEM,MSG_MINOPEN,0,0,
  597.    NM_ITEM,MSG_HOURAPEN,0,0,
  598.    NM_ITEM,MSG_HOUROPEN,0,0,
  599.    NM_ITEM,MSG_SHADOW,0,0,
  600.    NM_ITEM,MSG_STR12,0,0,
  601.    NM_ITEM,MSG_QUARTER,0,0,
  602.    NM_ITEM,MSG_HOURS,0,0,
  603.    NM_ITEM,MSG_MINUTES,0,0,
  604.    NM_ITEM,MSG_BORDER0,0,0,
  605.    NM_ITEM,MSG_BORDER1,0,0,
  606.    NM_ITEM,MSG_BORDER2,0,0,
  607.    NM_ITEM,MSG_BORDER3,0,0,
  608.   NM_TITLE,MSG_PATTERN,0,0,
  609.    NM_ITEM,MSG_COLOR0,0,0,
  610.    NM_ITEM,MSG_COLOR1,0,0,
  611.    NM_ITEM,MSG_COLOR2,0,0,
  612.    NM_ITEM,MSG_COLOR3,0,0
  613. };
  614.  
  615. #define NM_ITEMCOUNT (sizeof(MenuInfo)/(4*sizeof(UBYTE)))
  616.  
  617. CONST struct TagItem MenuTags[] = {
  618.   { GTMN_NewLookMenus,TRUE },
  619.   { TAG_DONE         ,NULL }
  620. };
  621.  
  622. LONG InitClock()
  623. { struct NewMenu menubuf[NM_ITEMCOUNT+1],*nm;
  624.   struct Gadget *gad;
  625.   CONST UBYTE *p;
  626.   LONG tmp,index,ret;
  627.   WORD i,num;
  628.  
  629.   LoadImage();
  630.   SetPattern();
  631.  
  632.   for(gad=&gb->GadgetBuf[0],p=&gadgetInfo[0],num=1,i=GB_GADCOUNT-1; i>=0; i--)
  633.   { gad->Width      = num;
  634.     gad->Height     = num;
  635.     gad->Flags      = *p++;
  636.     gad->Activation = num; /* GACT_RELVERIFY */
  637.     gad->GadgetType = *p++;
  638.     gad++;
  639.     gad[-1].NextGadget = gad;
  640.   }
  641.   gad[-1].NextGadget = NULL;
  642.  
  643.   MEMZEROL(&menubuf[0],sizeof(menubuf));
  644.   for(nm=&menubuf[0],p=&MenuInfo[0],i=NM_ITEMCOUNT-1; i>=0; i--)
  645.   { nm->nm_Type          = *p++;
  646.     if ((tmp=(BYTE)*p++) >= 0) tmp=(LONG)GetCatalogString(tmp);
  647.     nm->nm_Label         = (STRPTR)tmp;
  648.     nm->nm_Flags         = (UWORD)*p++;
  649.     if ((num=(BYTE)*p++) < 0) num=(((num&0x7f))<<5);
  650.     nm->nm_MutualExclude = (ULONG)num;
  651.     nm++;
  652.   }
  653.   menubuf[MENU_PROJECT_ABOUT].nm_CommKey = GetCatalogString(MSG_ABOUTKEY);
  654.   menubuf[MENU_PROJECT_QUIT].nm_CommKey  = GetCatalogString(MSG_QUITKEY);
  655.   menubuf[MENU_SETTINGS_SAVE].nm_CommKey = GetCatalogString(MSG_SAVEKEY);
  656.  
  657.   ret = 0;
  658.  
  659.   if ((gb->VisualInfo=GetVisualInfoA(PUB_SCREEN,NULL)) != NULL)
  660.   {
  661.     nm = &menubuf[0]; i = CHECKED;
  662.     nm[MENU_SETTINGS_SECONDS].nm_Flags
  663.      |= i & (gb->Seconds ? -1 : 0);
  664.     nm[MENU_SETTINGS_OVAL].nm_Flags
  665.      |= i & (gb->Oval ? -1 : 0);
  666.     index = MENU_SETTINGS_SHOW+gb->Show+1;
  667.     nm[index].nm_Flags
  668.      |= i;
  669.     index = MENU_SETTINGS_HANDS+gb->HandType+1;
  670.     nm[index].nm_Flags
  671.      |= i;
  672.     index = MENU_SETTINGS_HANDS+gb->HandWidth+6;
  673.     nm[index].nm_Flags
  674.      |= i;
  675.     nm[MENU_SETTINGS_SHADOW].nm_Flags
  676.      |= i & (gb->Shadow ? -1 : 0);
  677.     index = MENU_SETTINGS_BORDER+gb->BorderCount+1;
  678.     nm[index].nm_Flags
  679.      |= i;
  680.     nm[MENU_SETTINGS_BORDER_HIRES].nm_Flags
  681.      |= i & (gb->HiRes ? -1 : 0);
  682.     nm[MENU_SETTINGS_BORDER_INTERLACE].nm_Flags
  683.      |= i & (gb->Interlace ? -1 : 0);
  684.     index = MENU_SETTINGS_CHIME+gb->Chime+1;
  685.     nm[index].nm_Flags
  686.      |= i;
  687.     nm[MENU_SETTINGS_CHIME_SMART].nm_Flags
  688.      |= i & (gb->SmartHour ? -1 : 0);
  689.     nm[MENU_SETTINGS_USEIMAGE].nm_Flags
  690.      |= i & (gb->BFInfo.PictureObject && gb->UseImage ? -1 : 0);
  691.     nm[MENU_SETTINGS_CLOSEGAD].nm_Flags
  692.      |= i & (gb->CloseGad ? -1 : 0);
  693.  
  694.     if ((gb->Menus=CreateMenusA(&menubuf[0],NULL)) != NULL)
  695.       if (LayoutMenusA(gb->Menus,gb->VisualInfo,(struct TagItem *)MenuTags))
  696.         ret = OpenMainWindow();
  697.   }
  698.   return ret;
  699. }
  700.  
  701. /***************************************************************************/
  702. /*                                                                         */
  703. /* get argumets either from CLI or WB                                      */
  704. /*                                                                         */
  705. /***************************************************************************/
  706.  
  707. LONG GetArguments()
  708. { struct WBStartup *wm;
  709.   struct WBArg *arg;
  710.   STRPTR buf;
  711.  
  712.   if ((wm=gb->WbMsg) != NULL)
  713.   {
  714.     arg = wm->sm_ArgList;
  715.     if (wm->sm_NumArgs>1)
  716.       arg++;
  717.     gb->ProgArg.wa_Lock = arg->wa_Lock;
  718.     gb->ProgArg.wa_Name = arg->wa_Name;
  719.     gb->OldLock = CurrentDir(arg->wa_Lock);
  720.     gb->ChangedDir = -1;
  721.     MergeToolTypes();
  722.   }
  723.   else
  724.     if ((gb->NameBuf=(buf=AllocVec(124,MEMF_ANY))) != NULL)
  725.     {
  726.       gb->ProgArg.wa_Lock = GetProgramDir();
  727.       GetProgramName(buf,124);
  728.       gb->ProgArg.wa_Name = FilePart(buf);
  729.       ParseArgs(NULL,0);
  730.     }
  731.  
  732.   if (PUB_SCREEN == NULL)
  733.     return  0;
  734.  
  735.   return 1;
  736. }
  737.  
  738. /*
  739. ** read all tooltypes
  740. */
  741.  
  742. STATIC INLINE STRPTR stpcpy(STRPTR dst,STRPTR src)
  743. {
  744.   while((*dst++=*src++)); return(dst-1);
  745. }
  746.  
  747. VOID MergeToolTypes()
  748. { struct DiskObject *dobj;
  749.   STRPTR argstr,string,p;
  750.   LONG arglen,strln;
  751.   BPTR old_cd;
  752.   char **tt;
  753.  
  754.   argstr = (STRPTR)&gb->EasyBuf; *argstr = '\n'; arglen = 1; string=NULL;
  755.  
  756.   old_cd = CurrentDir(gb->ProgArg.wa_Lock);
  757.  
  758.   if ((dobj=GetDiskObject(gb->ProgArg.wa_Name)) != NULL)
  759.   {
  760.     tt = dobj->do_ToolTypes; strln = 1;
  761.     while (*tt != NULL)
  762.     {
  763.       strln+=strlen(*tt++)+1;
  764.     }
  765.  
  766.     if ((string=AllocVec((strln+sizeof(ULONG)-1)&~(sizeof(ULONG)-1),MEMF_ANY)) != NULL)
  767.     {
  768.       tt = dobj->do_ToolTypes; p=string;
  769.       while (*tt != NULL)
  770.       {
  771.         p=stpcpy(p,*tt++); *p++ = ' ';
  772.       }
  773.       *p = '\n';
  774.  
  775.       argstr = string; arglen = strln;
  776.     }
  777.  
  778.     FreeDiskObject(dobj);
  779.   }
  780.  
  781.   ParseArgs(argstr,arglen);
  782.  
  783.   if (string)
  784.     FreeVec(string);
  785.  
  786.   (VOID)CurrentDir(old_cd);
  787. }
  788.  
  789. /*
  790. ** parse arguments and set default values
  791. */
  792.  
  793. enum             {OPT_NULL=-1,OPT_TOP,OPT_LEFT,OPT_WIDTH,OPT_HEIGHT,OPT_SECONDS,
  794.                   OPT_PATTERN,OPT_OVAL,OPT_SHADOW,OPT_SHOWFACE,OPT_HANDTYPE,
  795.                   OPT_HANDWIDTH,OPT_DRAWPENS,OPT_BORDERTYPE,OPT_CHIME,OPT_CLOSEGAD,
  796.                   OPT_USEIMAGE,OPT_NOREMAP,OPT_IMAGE,OPT_PUBSCREEN,OPT_TASKPRI,
  797.                   OPT_SIZEOF};
  798.  
  799. #define TEMPLATE "/M,TOP/N,LEFT/N,WIDTH/N,HEIGHT/N,SECONDS/S,PATTERN/K,OVAL/S," \
  800.                  "SHADOW/S,SHOWFACE/N,HANDTYPE/N,HANDWIDTH/N,DRAWPENS/K,"       \
  801.                  "BORDERTYPE/N,CHIME/N,CLOSEGAD/S,USEIMAGE/S,NOREMAP/S,"        \
  802.                  "IMAGE/K,PUBSCREEN/K,TASKPRI/N"
  803.  
  804. CONST UBYTE Pens[] = {
  805.   2,0,2,0,2,1,2,2,2,2,0,1,2,3
  806. };
  807.  
  808. VOID ParseArgs(STRPTR argstr,LONG length)
  809. { struct RDArgs *rda,*args;
  810.   struct Screen *scr;
  811.   LONG result[OPT_SIZEOF+1],*res,def,tmp;
  812.   STRPTR tmpl;
  813.  
  814.   MEMZEROL(&result[0],sizeof(result));
  815.  
  816.   if ((rda=AllocDosObject(DOS_RDARGS,NULL)) != NULL)
  817.   {
  818.     rda->RDA_Source.CS_Buffer = argstr;
  819.     rda->RDA_Source.CS_Length = length;
  820.     tmpl = TEMPLATE; res = &result[0];
  821.     if (rda->RDA_Source.CS_Buffer == NULL)
  822.     {
  823.       res++; tmpl+=3;
  824.     }
  825.     args=ReadArgs(tmpl,res,rda);
  826.   }
  827.  
  828.   res = &result[1];
  829.  
  830.   def = 50;
  831.   if (res[OPT_TOP])
  832.   {
  833.     tmp = *(LONG *)res[OPT_TOP]; if (tmp >= 0) def = tmp;
  834.   }
  835.   gb->Top = def;
  836.  
  837.   def = 50;
  838.   if (res[OPT_LEFT])
  839.   {
  840.     tmp = *(LONG *)res[OPT_LEFT]; if (tmp >= 0) def = tmp;
  841.   }
  842.   gb->Left = def;
  843.  
  844.   def = 108;
  845.   if (res[OPT_WIDTH])
  846.   {
  847.     tmp = *(LONG *)res[OPT_WIDTH]; if (tmp >= 10) def = tmp;
  848.   }
  849.   gb->Width = def;
  850.  
  851.   def = 54;
  852.   if (res[OPT_HEIGHT])
  853.   {
  854.     tmp = *(LONG *)res[OPT_HEIGHT]; if (tmp >= 10) def = tmp;
  855.   }
  856.   gb->Height = def;
  857.  
  858.   gb->Seconds = res[OPT_SECONDS];
  859.  
  860.   ReadStr(&gb->Must[0],(STRPTR)res[OPT_PATTERN],&gb->Must[0],4);
  861.  
  862.   gb->Oval = res[OPT_OVAL];
  863.  
  864.   gb->Shadow = res[OPT_SHADOW];
  865.  
  866.   def = 1;
  867.   if (res[OPT_SHOWFACE])
  868.   {
  869.     tmp = *(LONG *)res[OPT_SHOWFACE]; if ((ULONG)tmp < 5) def = tmp;
  870.   }
  871.   gb->Show = def;
  872.  
  873.   def = 2;
  874.   if (res[OPT_HANDTYPE])
  875.   {
  876.     tmp = *(LONG *)res[OPT_HANDTYPE]; if ((ULONG)tmp < 4) def = tmp;
  877.   }
  878.   gb->HandType = def;
  879.  
  880.   def = 2;
  881.   if (res[OPT_HANDWIDTH])
  882.   {
  883.     tmp = *(LONG *)res[OPT_HANDWIDTH]; if ((ULONG)tmp < 5) def = tmp;
  884.   }
  885.   gb->HandWidth = def;
  886.  
  887.   ReadStr(&gb->Pens[0],(STRPTR)res[OPT_DRAWPENS],(STRPTR)&Pens[0],14);
  888.  
  889.   def = 6;
  890.   if (res[OPT_BORDERTYPE])
  891.   {
  892.     tmp = *(LONG *)res[OPT_BORDERTYPE]; if ((ULONG)tmp <= 2+4+8) def = tmp;
  893.   }
  894.   if (def & 4)
  895.   {
  896.     gb->HiRes = -1; def -= 4;
  897.   }
  898.   if (def & 8)
  899.   {
  900.     gb->Interlace = -1; def -= 8;
  901.   }
  902.   gb->BorderCount = def;
  903.  
  904.   def = 0;
  905.   if (res[OPT_CHIME])
  906.   {
  907.     tmp = *(LONG *)res[OPT_CHIME]; if ((ULONG)tmp <= 2+4) def = tmp;
  908.   }
  909.   if (def & 4)
  910.   {
  911.     gb->SmartHour = -1; def -= 4;
  912.   }
  913.   gb->Chime = def;
  914.  
  915.   gb->CloseGad = res[OPT_CLOSEGAD];
  916.  
  917.   gb->UseImage = res[OPT_USEIMAGE];
  918.  
  919.   gb->NoRemap = res[OPT_NOREMAP];
  920.  
  921.   if (res[OPT_IMAGE])
  922.     if ((gb->BFInfo.PictureName=AllocVec(1+strlen((STRPTR)res[OPT_IMAGE]),MEMF_ANY)) != NULL)
  923.       strcpy(gb->BFInfo.PictureName,(STRPTR)res[OPT_IMAGE]);
  924.  
  925.   if ((scr=(struct Screen *)res[OPT_PUBSCREEN]) != NULL)
  926.   { if ((scr=LockPubScreen((STRPTR)scr)) == NULL)
  927.       scr = LockPubScreen((STRPTR)scr); }
  928.   else
  929.     scr = LockPubScreen((STRPTR)scr);
  930.   PUB_SCREEN = scr;
  931.  
  932.   if (res[OPT_TASKPRI])
  933.   {
  934.     tmp = *(LONG *)res[OPT_TASKPRI]; if (tmp > 5) tmp = 5;
  935.     gb->OldPri = SetTaskPri((struct Task *)gb->OurTask,tmp);
  936.     gb->ChangedPri = -1;
  937.   }
  938.  
  939.   if (args != NULL)
  940.     FreeArgs(args);
  941.  
  942.   if (rda != NULL)
  943.     FreeDosObject(DOS_RDARGS,rda);
  944. }
  945.  
  946. /*
  947. ** init pen-buffer with `def' and replace with src (if non zero)
  948. */
  949.  
  950. VOID ReadStr(UBYTE *dst,UBYTE *src,UBYTE *def,LONG cnt)
  951. {
  952.   CopyMem(def,dst,cnt);
  953.  
  954.   if (src != NULL)
  955.     if (*src=='x' || *src=='X') /* hex */
  956.       do
  957.       { if (!*src++ || !*src++)
  958.           return;
  959.         *dst++ = (XtoD(src[-1])<<4) + XtoD(*src);
  960.       } while (--cnt);
  961.     else
  962.       do /* decimal */
  963.       { if (!*src)
  964.           return;
  965.         *dst++ = XtoD(*src++);
  966.       } while (--cnt);
  967. }
  968.  
  969. LONG XtoD(LONG a)
  970. {
  971.   if (a>='0' && a<='9')
  972.     return (a-'0');
  973.   if (a>='a' && a<='f')
  974.     return (a-'a'+10);
  975.   if (a>='A' && a<='F')
  976.     return (a-'A'+10);
  977.   return 0;
  978. }
  979.  
  980. /***************************************************************************/
  981. /*                                                                         */
  982. /* open all devices                                                        */
  983. /*                                                                         */
  984. /***************************************************************************/
  985.  
  986. LONG OpenDevs()
  987. { LONG ret = 0;
  988.  
  989.   if ((gb->WindowPort=CreateMsgPort()) != NULL)
  990.     if ((gb->TimerPort=CreateMsgPort()) != NULL)
  991.       if ((gb->TimerIO=CreateIORequest(gb->TimerPort,sizeof(struct timerequest))) != NULL)
  992.         if (!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)gb->TimerIO,0))
  993.         {
  994.           gb->TimerOpen = -1;
  995.           if ((gb->AudioPort=CreateMsgPort()) != NULL)
  996.             if ((gb->AudioIO[0]=CreateIORequest(gb->AudioPort,sizeof(struct IOAudio))) != NULL)
  997.               if ((gb->AudioIO[1]=CreateIORequest(gb->AudioPort,sizeof(struct IOAudio))) != NULL)
  998.                 if (!OpenDevice(AUDIONAME,0,(struct IORequest *)gb->AudioIO[0],0))
  999.                 {
  1000.                   gb->AudioOpen = -1;
  1001.                   if ((gb->WaveForm=AllocMem(8,MEMF_CHIP|MEMF_PUBLIC|MEMF_CLEAR)) != NULL)
  1002.                   {
  1003.                     ((ULONG *)gb->WaveForm)[0]=0x7f807f80; /* rectangle */
  1004.                     ret = 1;
  1005.                   }
  1006.                 }
  1007.         }
  1008.   return ret;
  1009. }
  1010.  
  1011. /***************************************************************************/
  1012. /*                                                                         */
  1013. /* open all libraries                                                      */
  1014. /*                                                                         */
  1015. /***************************************************************************/
  1016.  
  1017. LONG OpenLibs()
  1018. { LONG ret = 0;
  1019.  
  1020.   if ((gb->DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37L)) != NULL)
  1021.     if ((gb->IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L)) != NULL)
  1022.       if ((gb->GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L)) != NULL)
  1023.         if ((gb->GadtoolsBase=OpenLibrary("gadtools.library",37L)) != NULL)
  1024.           if ((gb->IconBase=OpenLibrary("icon.library",37L)) != NULL)
  1025.           {
  1026.             gb->DataTypesBase = OpenLibrary("datatypes.library",39L);
  1027.             if ((gb->LocaleBase=(struct LocaleBase *)OpenLibrary("locale.library",38L)) != NULL)
  1028.             {
  1029.               gb->Catalog = OpenCatalogA(NULL,"tolleuhr.catalog",NULL);
  1030.             }
  1031.             ret = 1;
  1032.           }
  1033.   return ret;
  1034. }
  1035.  
  1036. /***************************************************************************/
  1037. /*                                                                         */
  1038. /* main function                                                           */
  1039. /*                                                                         */
  1040. /***************************************************************************/
  1041.  
  1042. VOID Main()
  1043. { struct Process *proc;
  1044.   STRPTR buf;
  1045.   ULONG mask;
  1046.  
  1047.   gb->OurTask = proc = (struct Process *)FindTask(NULL);
  1048.  
  1049.   if (!proc->pr_CLI)
  1050.   {
  1051.     WaitPort(&proc->pr_MsgPort);
  1052.     gb->WbMsg = (struct WBStartup *)GetMsg(&proc->pr_MsgPort);
  1053.   }
  1054.  
  1055.   if (OpenLibs())
  1056.   {
  1057.     if (OpenDevs())
  1058.     {
  1059.       if (GetArguments())
  1060.       {
  1061.         if (InitClock())
  1062.         {
  1063.           for(;;)
  1064.           {
  1065.             mask = 1L<<SIGBREAKB_CTRL_C | 1L<<gb->WindowPort->mp_SigBit |
  1066.                    1L<<gb->TimerPort->mp_SigBit | 1L<<gb->AudioPort->mp_SigBit;
  1067.  
  1068.             if (gb->AboutReq)
  1069.               mask |= 1L<<gb->AboutReq->UserPort->mp_SigBit;
  1070.  
  1071.             if (Wait(mask) & SIGBREAKF_CTRL_C) /* User-Break */
  1072.               break;
  1073.  
  1074.             if (GetMsg(gb->TimerPort))
  1075.             {
  1076.               if (NextTick())
  1077.               {
  1078.                 ZifferBlatt(); TestIfAlarm();
  1079.               }
  1080.               Zeichnen();
  1081.             }
  1082.  
  1083.             if (GetMsg(gb->AudioPort))
  1084.               PlayNote();
  1085.  
  1086.             CheckAboutReq();
  1087.  
  1088.             CheckWindows();
  1089.  
  1090.             if (gb->EndAll)
  1091.               break;
  1092.           }
  1093.         }
  1094.         CloseGfx();
  1095.  
  1096.         if (gb->ChangedPri)
  1097.           (VOID)SetTaskPri((struct Task *)gb->OurTask,gb->OldPri);
  1098.  
  1099.         if ((buf=gb->NameBuf) != NULL)
  1100.           FreeVec(buf);
  1101.  
  1102.         if (gb->ChangedDir)
  1103.           (VOID)CurrentDir(gb->OldLock);
  1104.       }
  1105.     }
  1106.     CloseDevs();
  1107.   }
  1108.   CloseLibs();
  1109.  
  1110.   if (gb->WbMsg)
  1111.   {
  1112.     Forbid();
  1113.     ReplyMsg((struct Message *)gb->WbMsg);
  1114.   }
  1115. }
  1116.  
  1117. /***************************************************************************/
  1118. /*                                                                         */
  1119. /* close all libraries                                                     */
  1120. /*                                                                         */
  1121. /***************************************************************************/
  1122.  
  1123. VOID CloseLibs()
  1124. { struct Library *lib;
  1125.  
  1126.   if (gb->LocaleBase != NULL)
  1127.   {
  1128.     CloseCatalog(gb->Catalog); CloseLibrary((struct Library *)gb->LocaleBase);
  1129.   }
  1130.   if ((lib=gb->DataTypesBase) != NULL)
  1131.     CloseLibrary(lib);
  1132.   if ((lib=gb->IconBase) != NULL)
  1133.     CloseLibrary(lib);
  1134.   if ((lib=gb->GadtoolsBase) != NULL)
  1135.     CloseLibrary(lib);
  1136.   if ((lib=(struct Library *)gb->GfxBase) != NULL)
  1137.     CloseLibrary(lib);
  1138.   if ((lib=(struct Library *)gb->IntuitionBase) != NULL)
  1139.     CloseLibrary(lib);
  1140.   if ((lib=(struct Library *)gb->DOSBase) != NULL)
  1141.     CloseLibrary(lib);
  1142. }
  1143.  
  1144. /***************************************************************************/
  1145. /*                                                                         */
  1146. /* close all devices                                                       */
  1147. /*                                                                         */
  1148. /***************************************************************************/
  1149.  
  1150. VOID StopIO(struct IORequest *ioReq)
  1151. {
  1152.   AbortIO(ioReq); WaitIO(ioReq);
  1153. }
  1154.  
  1155. VOID CloseDevs()
  1156. { struct IORequest *ioreq,*io;
  1157.   struct MsgPort *port;
  1158.   APTR buf;
  1159.  
  1160.   if (gb->AudioOpen)
  1161.   {
  1162.     if (gb->AudioSent[1])
  1163.       StopIO((struct IORequest *)gb->AudioIO[1]);
  1164.     io = (struct IORequest *)gb->AudioIO[0];
  1165.     if (gb->AudioSent[0])
  1166.       StopIO(io);
  1167.     if (gb->SoundOn)
  1168.       EndTune();
  1169.     CloseDevice(io);
  1170.   }
  1171.  
  1172.   if ((ioreq=(struct IORequest *)gb->AudioIO[1]) != NULL)
  1173.     DeleteIORequest(ioreq);
  1174.   if ((ioreq=(struct IORequest *)gb->AudioIO[0]) != NULL)
  1175.     DeleteIORequest(ioreq);
  1176.   if ((port=gb->AudioPort) != NULL)
  1177.     DeleteMsgPort(port);
  1178.   if ((buf=gb->WaveForm) != NULL)
  1179.     FreeMem(buf,8);
  1180.  
  1181.   if (gb->TimerOpen)
  1182.   {
  1183.     io = (struct IORequest *)gb->TimerIO;
  1184.     if (gb->TimerSent)
  1185.       StopIO(io);
  1186.     CloseDevice(io);
  1187.   }
  1188.  
  1189.   if ((ioreq=(struct IORequest *)gb->TimerIO) != NULL)
  1190.     DeleteIORequest(ioreq);
  1191.   if ((port=gb->TimerPort) != NULL)
  1192.     DeleteMsgPort(port);
  1193.  
  1194.   if ((port=gb->WindowPort) != NULL)
  1195.     DeleteMsgPort(port);
  1196. }
  1197.  
  1198. /***************************************************************************/
  1199. /*                                                                         */
  1200. /* close graphic stuff                                                     */
  1201. /*                                                                         */
  1202. /***************************************************************************/
  1203.  
  1204. VOID NewSize1()
  1205. { PLANEPTR buf,*p;
  1206.   LONG i;
  1207.  
  1208.   if ((buf=gb->Buf) != NULL)
  1209.     FreeRaster(buf,gb->Width2,gb->Height2);
  1210.  
  1211.   p=&gb->BitMap1.Planes[0];
  1212.   if ((i=gb->BitMap1.Depth) > 0)
  1213.     do
  1214.     { if ((buf=*p) != NULL)
  1215.         FreeRaster(buf,gb->Width2,gb->Height2);
  1216.       *p++=NULL;
  1217.     } while(--i);
  1218. }
  1219.  
  1220. /*
  1221. ** discard `About'
  1222. */
  1223.  
  1224. VOID CloseAboutReq()
  1225. { struct Window *req;
  1226.  
  1227.   if ((req=gb->AboutReq) != NULL)
  1228.   {
  1229.     FreeSysRequest(req); gb->AboutReq = NULL;
  1230.   }
  1231. }
  1232.  
  1233. /*
  1234. ** discard all windows and other gfx stuff
  1235. */
  1236.  
  1237. VOID CloseGfx()
  1238. { struct Screen *scr;
  1239.   struct Menu *menus;
  1240.   Object *img;
  1241.   APTR vi;
  1242.  
  1243.   NewSize1();
  1244.   CloseAboutReq();
  1245.   FreeWindow(&gb->AlarmWin);
  1246.   FreeWindow(&gb->ColorWin);
  1247.   CloseWindowSafely(gb->MainWin);
  1248.   if ((menus=gb->Menus) != NULL)
  1249.     FreeMenus(menus);
  1250.   if ((vi=gb->VisualInfo) != NULL)
  1251.     FreeVisualInfo(vi);
  1252.   if ((img=gb->BFInfo.PictureObject) != NULL)
  1253.     DisposeDTObject(img);
  1254.   if ((scr=PUB_SCREEN) != NULL)
  1255.     UnlockPubScreen(NULL,scr);
  1256. }
  1257.  
  1258. /*
  1259. ** close a tool window
  1260. */
  1261.  
  1262. VOID FreeWindow(struct WinGad *wg)
  1263. { struct Window *win;
  1264.  
  1265.   if ((win=wg->Win) != NULL)
  1266.   {
  1267.     CloseWindowSafely(win);
  1268.     wg->Win = NULL;
  1269.     FreeGadgets(wg->Gad);
  1270.     wg->Gad = NULL;
  1271.   }
  1272. }
  1273.  
  1274. /*
  1275. ** close window with shared IDCMP
  1276. */
  1277.  
  1278. VOID CloseWindowSafely(struct Window *win)
  1279. { struct Node *msg,*succ;
  1280.  
  1281.   Forbid();
  1282.   msg=win->UserPort->mp_MsgList.lh_Head; /* assumes valid port */
  1283.   while ((succ=msg->ln_Succ)!=NULL)
  1284.   { if (((struct IntuiMessage *)msg)->IDCMPWindow==win)
  1285.     {
  1286.       Remove(msg); ReplyMsg((struct Message *)msg);
  1287.     }
  1288.     msg=succ;
  1289.   }
  1290.   win->UserPort=NULL;
  1291.   ModifyIDCMP(win,0L);
  1292.   Permit();
  1293.   ClearMenuStrip(win);
  1294.   CloseWindow(win);
  1295. }
  1296.  
  1297. /***************************************************************************/
  1298. /*                                                                         */
  1299. /* process all input events                                                */
  1300. /*                                                                         */
  1301. /***************************************************************************/
  1302.  
  1303. VOID CheckAboutReq()
  1304. { struct Window *req;
  1305.  
  1306.   if ((req=gb->AboutReq) != NULL)
  1307.     if (SysReqHandler(req,NULL,FALSE) != -2)
  1308.       CloseAboutReq();
  1309. }
  1310.  
  1311. /*
  1312. ** process all windows with shared IDCMP
  1313. */
  1314.  
  1315. VOID CheckWindows()
  1316. { struct IntuiMessage *imsg;
  1317.   struct Window *iwin;
  1318.   ULONG class,code;
  1319.   APTR iadr;
  1320.   LONG tmp;
  1321.  
  1322.   while ((imsg=GT_GetIMsg(gb->WindowPort)) != NULL)
  1323.   { class = imsg->Class;
  1324.     code  = imsg->Code;
  1325.     iadr  = imsg->IAddress;
  1326.     iwin  = imsg->IDCMPWindow;
  1327.     GT_ReplyIMsg(imsg);
  1328.     if (gb->MainWin == iwin)
  1329.     { switch (class)
  1330.       { case NEWSIZE:
  1331.           NewSize1();
  1332.           if ((gb->EndAll=NewSize2()))
  1333.             return;
  1334.           Rahmen();
  1335.           ZifferBlatt();
  1336.           Zeichnen();
  1337.           break;
  1338.         case REFRESHWINDOW:
  1339.           gb->ReDrawx1=(tmp=gb->BoLeft);
  1340.           gb->ReDrawx2=tmp+gb->Width2-1;
  1341.           gb->ReDrawy1=(tmp=gb->BoTop);
  1342.           gb->ReDrawy2=tmp+gb->Height2-1;
  1343.           BeginRefresh(gb->MainWin);
  1344.           Rahmen();
  1345.           Zeichnen();
  1346.           EndRefresh(gb->MainWin,TRUE);
  1347.           break;
  1348.         case MENUPICK:
  1349.           HandleMenus(code);
  1350.           if (gb->EndAll)
  1351.             return;
  1352.           break;
  1353.         case CLOSEWINDOW:
  1354.           if ((gb->EndAll=gb->CloseGad))
  1355.             return;
  1356.           break;
  1357.         case ACTIVEWINDOW:
  1358.           gb->Active = -1;
  1359.           Rahmen();
  1360.           break;
  1361.         case INACTIVEWINDOW:
  1362.           gb->Active = 0;
  1363.           Rahmen();
  1364.           break;
  1365.       }
  1366.     }
  1367.     else
  1368.       if (gb->ColorWin.Win == iwin)
  1369.       { if (class == CLOSEWINDOW || class == GADGETUP)
  1370.         { if (class!=CLOSEWINDOW) /* kann nur das Palette-Gadget sein */
  1371.           { *gb->Color = code;
  1372.             SetPattern();
  1373.             Rahmen();
  1374.             ZifferBlatt();
  1375.             Zeichnen();
  1376.           }
  1377.           FreeWindow(&gb->ColorWin);
  1378.         }
  1379.       }
  1380.       else
  1381.         if (gb->AlarmWin.Win == iwin)
  1382.         { if (class==CLOSEWINDOW || class==MOUSEMOVE || class==GADGETUP)
  1383.           { if (class!=CLOSEWINDOW)
  1384.             { switch(((struct Gadget *)iadr)->GadgetID)
  1385.               { case 1:
  1386.                   gb->St = code;
  1387.                   goto endit;
  1388.                 case 2:
  1389.                   gb->Mi = code;
  1390.                   goto endit;
  1391.                 case 3:
  1392.                   gb->AlStd = gb->St; gb->AlMin = gb->Mi; gb->Alarm = -1;
  1393.                 case 4:
  1394.                   break;
  1395.               }
  1396.             }
  1397.             FreeWindow(&gb->AlarmWin);
  1398.             if (gb->Alarm)
  1399.             { struct MenuItem *item=ItemAddress(gb->Menus,FULLMENUNUM(1,7,1));
  1400.               if (!(item->Flags&CHECKED))
  1401.               { ClearMenuStrip(gb->MainWin);
  1402.                 item->Flags |= CHECKED;
  1403.                 ResetMenuStrip(gb->MainWin,gb->Menus);
  1404.               }
  1405.             }
  1406. endit:      ;
  1407.           }
  1408.         }
  1409.   }
  1410. }
  1411.  
  1412. /*
  1413. ** function for Menu-Handling
  1414. */
  1415.  
  1416. CONST UWORD ColorWinInfo[] = {
  1417.   CLOSEWINDOW | PALETTEIDCMP, MSG_CHOOSE,
  1418.   1,
  1419.   4,2,144,68,0,PALETTE_KIND,
  1420. };
  1421.  
  1422. CONST UWORD AlarmWinInfo[] = {
  1423.   CLOSEWINDOW | BUTTONIDCMP | SLIDERIDCMP, MSG_ALARM,
  1424.   4,
  1425.   42,15,20,39,0         ,SLIDER_KIND,
  1426.   82,15,20,39,0         ,SLIDER_KIND,
  1427.    2,58,70,12,MSG_USE   ,BUTTON_KIND,
  1428.   76,58,70,12,MSG_CANCEL,BUTTON_KIND,
  1429. };
  1430.  
  1431. CONST struct TagItem AlarmGadTags1[] = {
  1432.   { GTSL_Min        ,1               },
  1433.   { GTSL_Max        ,12              },
  1434.   { GTSL_MaxLevelLen,10              },
  1435.   { GTSL_LevelPlace ,PLACETEXT_ABOVE },
  1436.   { PGA_FREEDOM     ,LORIENT_VERT    },
  1437.   { GA_RelVerify    ,TRUE            },
  1438.   { TAG_DONE        ,NULL            }
  1439. };
  1440.  
  1441. CONST struct TagItem AlarmGadTags2[] = {
  1442.   { GTSL_Min        ,0               },
  1443.   { GTSL_Max        ,59              },
  1444.   { GTSL_MaxLevelLen,5               },
  1445.   { GTSL_LevelPlace ,PLACETEXT_ABOVE },
  1446.   { PGA_FREEDOM     ,LORIENT_VERT    },
  1447.   { GA_RelVerify    ,TRUE            },
  1448.   { TAG_DONE        ,NULL            }
  1449. };
  1450.  
  1451. VOID HandleMenus(ULONG code)
  1452. { struct TagItem tags[6],*tt[4];
  1453.   struct MenuItem *item;
  1454.   struct Window *req;
  1455.   ULONG mnum,inum,snum,*p;
  1456.   BYTE check;
  1457.  
  1458.   while ((UWORD)code != MENUNULL)
  1459.   {
  1460.     item = ItemAddress(gb->Menus,code);
  1461.     mnum = MENUNUM(code); inum = ITEMNUM(code); snum = SUBNUM(code);
  1462.     (UWORD)code = item->NextSelect;
  1463.  
  1464.     switch (mnum)
  1465.     {
  1466.        case 0: /* Project */
  1467.          switch (inum)
  1468.          {
  1469.            case 0: /* About */
  1470.              if (gb->AboutReq == NULL)
  1471.              {
  1472.                gb->EasyBuf.es_StructSize   = 5*sizeof(ULONG);
  1473.                gb->EasyBuf.es_Flags        = 0;
  1474.                gb->EasyBuf.es_Title        = GetCatalogString(MSG_ABOUT);
  1475.                gb->EasyBuf.es_TextFormat   = PROGNAME;
  1476.                gb->EasyBuf.es_GadgetFormat = GetCatalogString(MSG_DESCRIPTION);
  1477.                req = BuildEasyRequestArgs(gb->MainWin,&gb->EasyBuf,NULL,NULL);
  1478.                if ((ULONG)req>1)
  1479.                  gb->AboutReq = req;
  1480.              }
  1481.              break;
  1482.            case 1: /* Quit */
  1483.              gb->EndAll = -1; return;
  1484.              break;
  1485.          }
  1486.          break;
  1487.        case 1: /* Settings */
  1488.          check = (item->Flags&CHECKED ? 1 : 0);
  1489.          switch (inum)
  1490.          {
  1491.            case  0: /* Seconds */
  1492.              gb->Seconds = check;
  1493.              if (gb->TimerSent)
  1494.              {
  1495.                AbortIO((struct IORequest *)gb->TimerIO);
  1496.                WaitIO((struct IORequest *)gb->TimerIO);
  1497.                gb->TimerSent = 0;
  1498.              }
  1499.              NextTick();
  1500.              break;
  1501.            case  1: /* Oval */
  1502.              gb->Oval = check;
  1503.              break;
  1504.            case  2: /* Show */
  1505.              if (check)
  1506.                gb->Show = snum;
  1507.              break;
  1508.            case  3: /* Hands */
  1509.              if (check)
  1510.                switch (snum)
  1511.                { case 0: case 1: case 2: case 3:
  1512.                    gb->HandType  = snum;
  1513.                    break;
  1514.                  case 5: case 6: case 7: case 8: case 9:
  1515.                    gb->HandWidth = snum-5;
  1516.                    break;
  1517.                }
  1518.              break;
  1519.            case  4: /* Shadow */
  1520.              gb->Shadow = check;
  1521.              break;
  1522.            case  5: /* Border */
  1523.              switch (snum)
  1524.              { case 0: case 1: case 2:
  1525.                  if (check)
  1526.                    gb->BorderCount = snum;
  1527.                  break;
  1528.                case 4:
  1529.                  gb->HiRes = check;
  1530.                  break;
  1531.                case 5:
  1532.                  gb->Interlace = check;
  1533.                  break;
  1534.              }
  1535.              break;
  1536.            case  6: /* Chime */
  1537.              switch (snum)
  1538.              { case 0: case 1: case 2:
  1539.                  if (check)
  1540.                    gb->Chime = snum;
  1541.                  break;
  1542.                case 4:
  1543.                  gb->SmartHour = check;
  1544.                  break;
  1545.              }
  1546.            case  7: /* Alarm */
  1547.              switch (snum)
  1548.              {
  1549.                case 0:
  1550.                  if (gb->AlarmWin.Win == NULL)
  1551.                  {
  1552.                    gb->St = gb->AlStd; tt[0] = &tags[0];
  1553.                    p = (ULONG *)tt[0];
  1554.                    *p++ = GTSL_Level; *p++ = gb->AlStd;
  1555.                    *p++ = GTSL_LevelFormat; *p++ = (ULONG)"%2ld";
  1556.                    *p++ = TAG_MORE; *p = (ULONG)&AlarmGadTags1[0];
  1557.                    gb->Mi = gb->AlMin; tt[1] = &tags[3];
  1558.                    p = (ULONG *)tt[1];
  1559.                    *p++ = GTSL_Level; *p++ = gb->AlMin;
  1560.                    *p++ = GTSL_LevelFormat; *p++ = (ULONG)"%2ld";
  1561.                    *p++ = TAG_MORE; *p = (ULONG)&AlarmGadTags2[0];
  1562.                    tt[2] = NULL; tt[3] = NULL;
  1563.                    CreateRequest(&gb->AlarmWin,(struct wInfo *)&AlarmWinInfo[0],&tt[0]);
  1564.                  }
  1565.                  break;
  1566.                case 1:
  1567.                  gb->Alarm = check;
  1568.                  break;
  1569.              }
  1570.              break;
  1571.            case  8: /* UseImage */
  1572.              if (!(gb->UseImage=check))
  1573.                OnMenu(gb->MainWin,FULLMENUNUM(3,NOITEM,NOSUB));
  1574.              else
  1575.                OffMenu(gb->MainWin,FULLMENUNUM(3,NOITEM,NOSUB));
  1576.              break;
  1577.            case  9: /* CloseGadget */
  1578.              gb->CloseGad = check;
  1579.              break;
  1580.            case 11: /* Save Settings */
  1581.              SaveSettings();
  1582.              break;
  1583.          }
  1584.          break;
  1585.        case 2: /* Colours */
  1586.        case 3: /* Pattern */
  1587.          if (gb->ColorWin.Win == NULL)
  1588.          {
  1589.            gb->Color = (mnum == 2 ? &gb->Pens[inum] : &gb->Must[inum]);
  1590.            tt[0] = &tags[0];
  1591.            p = (ULONG *)tt[0];
  1592.            *p++ = GTPA_Depth; *p++ = gb->BitMap1.Depth; *p = TAG_DONE;
  1593.            CreateRequest(&gb->ColorWin,(struct wInfo *)&ColorWinInfo[0],&tt[0]);
  1594.          }
  1595.          break;
  1596.     }
  1597.   }
  1598.   NewSize1();
  1599.   if ((gb->EndAll=NewSize2()))
  1600.     return;
  1601.   Rahmen();
  1602.   ZifferBlatt();
  1603.   Zeichnen();
  1604. }
  1605.  
  1606. /***************************************************************************/
  1607. /*                                                                         */
  1608. /* resize invisible gadgets, init hidden drawing area                      */
  1609. /*                                                                         */
  1610. /***************************************************************************/
  1611.  
  1612. CONST WORD Sizes[][4] = { /* Für Gadgets */
  1613.   {  0, 0, 3, 2 },
  1614.   { -3, 0, 3, 2 },
  1615.   { -3,-2, 3, 2 },
  1616.   {  0, 2, 0,-4 }
  1617. };
  1618.  
  1619. LONG NewSize2()
  1620. { struct Window *win;
  1621.   struct Gadget *gad;
  1622.   PLANEPTR *p;
  1623.   LONG tmp,w,w2,h,h2,bc,ret;
  1624.   WORD i,j,k,newsize,*s;
  1625.  
  1626.   bc = gb->BorderCount;
  1627.   tmp = bc; if (gb->HiRes) tmp += (bc==2)<<1;
  1628.   gb->BoLeft = tmp;
  1629.   tmp = bc; if (gb->Interlace) tmp += (bc==2)<<1;
  1630.   gb->BoTop  = tmp;
  1631.  
  1632.   win = gb->MainWin;
  1633.  
  1634.   w = win->Width;  gb->Width  = w;
  1635.   h = win->Height; gb->Height = h;
  1636.  
  1637.   w2 = w-(gb->BoLeft<<1); gb->Width2  = w2;
  1638.   h2 = h-(gb->BoTop<<1);  gb->Height2 = h2;
  1639.  
  1640.   gb->xDouble = (gb->xMask == -2 && w2 > 12);
  1641.   gb->yDouble = (gb->yMask == -2 && h2 > 12);
  1642.  
  1643.   tmp = 0; if (w2 > 25) tmp = (w2 > 50 ? 2 : 1);
  1644.   gb->xOffset = tmp;
  1645.   tmp = 0; if (h2 > 25) tmp = (h2 > 50 ? 2 : 1);
  1646.   gb->yOffset = tmp;
  1647.  
  1648.   tmp = w; if (w > h) tmp = h; newsize = tmp/8;
  1649.  
  1650.   if (gb->GadSize != newsize)
  1651.   { gb->GadSize = newsize;
  1652.     RemoveGList(gb->MainWin,&gb->GadgetBuf[0],-1);
  1653.     for (gad=&gb->GadgetBuf[0],s=(WORD *)&Sizes[0],i=GB_GADCOUNT-1; i>=0; gad++,i--)
  1654.       for (j=4-1,k=2; j>=0; k++,j--)
  1655.         ((UWORD *)gad)[k] = *s++*gb->GadSize;
  1656.     AddGList(gb->MainWin,&gb->GadgetBuf[0],0,4,NULL);
  1657.   }
  1658.  
  1659.   InitBitMap(&gb->BitMap1,PUB_SCREEN->BitMap.Depth,gb->Width2,gb->Height2);
  1660.  
  1661.   ret = 1;
  1662.  
  1663.   for(p=&gb->BitMap1.Planes[0],i=gb->BitMap1.Depth; i!=0; i--)
  1664.     if ((*p++=AllocRaster(gb->Width2,gb->Height)) == NULL)
  1665.       return ret;
  1666.  
  1667.   InitRastPort(&gb->RPort2); gb->RPort2.BitMap = &gb->BitMap1;
  1668.  
  1669.   if ((gb->Buf=AllocRaster(gb->Width2,gb->Height)) != NULL)
  1670.   {
  1671.     gb->RPort2.TmpRas  = InitTmpRas(&gb->TempRas,gb->Buf,RASSIZE(gb->Width2,gb->Height));
  1672.     InitArea(&gb->AreaInfo,&gb->Table[0],5);
  1673.     gb->RPort2.AreaInfo= &gb->AreaInfo;
  1674.     ret = 0;
  1675.   }
  1676.  
  1677.   return ret;
  1678. }
  1679.  
  1680. /***************************************************************************/
  1681. /*                                                                         */
  1682. /* issue a timer request                                                   */
  1683. /*                                                                         */
  1684. /***************************************************************************/
  1685.  
  1686. ULONG NextTick()
  1687. { struct timerequest *treq = gb->TimerIO;
  1688.   ULONG tmp,old,std,min,sec;
  1689.  
  1690.   treq->tr_node.io_Command = TR_GETSYSTIME;
  1691.   DoIO(&treq->tr_node);
  1692.   treq->tr_time.tv_micro = 1100000-treq->tr_time.tv_micro;
  1693.                                /* ^ Ein ganz besonders netter Effekt: Das Timer */
  1694.                                /* Device rundet aktuelle Zeit und Wartezeit ab  */
  1695.   sec = treq->tr_time.tv_secs;
  1696.   tmp = 0; if (!gb->Seconds) tmp = 59-sec%60;
  1697.   treq->tr_time.tv_secs = tmp;
  1698.   treq->tr_node.io_Command = TR_ADDREQUEST;
  1699.   SendIO(&treq->tr_node);
  1700.   gb->TimerSent = -1;
  1701.  
  1702.   old=gb->Min;
  1703.   min=sec/60;
  1704.   gb->Sec=sec%60;
  1705.   std=min/12;
  1706.   gb->Min=(min%=60);
  1707.   gb->Std=std%60;
  1708.  
  1709.   return (min-old); /* sec==0 ist unzuverlässig bei hoher CPU-Auslastung */
  1710. }
  1711.  
  1712. /***************************************************************************/
  1713. /*                                                                         */
  1714. /* draw border                                                             */
  1715. /*                                                                         */
  1716. /***************************************************************************/
  1717.  
  1718. VOID Rahmen()
  1719. { struct RastPort *rp = gb->RPort1;
  1720.   ULONG pen,pen11,pen12;
  1721.   LONG w,h,bl,bt;
  1722.  
  1723.   if (gb->BorderCount)
  1724.   {
  1725.     w = gb->Width; h = gb->Height;
  1726.  
  1727.     pen11 = gb->Pens[11]; pen12 = gb->Pens[12];
  1728.     if (gb->Active && gb->BorderCount == 1)
  1729.     {
  1730.       pen=pen11; pen11=pen12; pen12=pen;
  1731.     }
  1732.  
  1733.     SetAPen(rp,pen11);
  1734.     Move(rp,1  ,h-1);
  1735.     Draw(rp,w-1,h-1);
  1736.     Draw(rp,w-1,1  );
  1737.     SetAPen(rp,pen12);
  1738.     Move(rp,0  ,h-1);
  1739.     Draw(rp,0  ,0  );
  1740.     Draw(rp,w-1,0  );
  1741.  
  1742.     if (gb->BorderCount == 2)
  1743.     {
  1744.       bl = gb->BoLeft; bt = gb->BoTop;
  1745.       SetAPen(rp,gb->Pens[12]);
  1746.       Move(rp,bl  ,h-bt);
  1747.       Draw(rp,w-bl,h-bt);
  1748.       Draw(rp,w-bl,bt  );
  1749.       SetAPen(rp,gb->Pens[11]);
  1750.       Move(rp,bl-1,h-bt);
  1751.       Draw(rp,bl-1,bt-1);
  1752.       Draw(rp,w-bl,bt-1);
  1753.       pen = gb->Pens[10]; if (gb->Active) pen = gb->Pens[13];
  1754.       SetAPen(rp,pen);
  1755.  
  1756.       if (gb->HiRes)
  1757.       {
  1758.         RectFill(rp,1,1,2,h-2);
  1759.         RectFill(rp,w-3,1,w-2,h-2);
  1760.       }
  1761.  
  1762.       if (gb->Interlace)
  1763.       {
  1764.         RectFill(rp,1,1,w-2,2);
  1765.         RectFill(rp,1,h-3,w-2,h-2);
  1766.       }
  1767.     }
  1768.   }
  1769.   SetAPen(rp,gb->Pens[0]);
  1770. }
  1771.  
  1772. /***************************************************************************/
  1773. /*                                                                         */
  1774. /* create the clock                                                        */
  1775. /*                                                                         */
  1776. /***************************************************************************/
  1777.  
  1778. CONST BYTE sinus[] = { /* sinus-Tabelle */
  1779.   0,13,26,39,52,64,75,85,94,103,110,116,121,124,126,
  1780.   127,126,124,121,116,110,103,94,85,75,64,52,39,26,13,
  1781.   0,-13,-26,-39,-52,-64,-75,-85,-94,-103,-110,-116,-121,-124,-126,
  1782.   -127,-126,-124,-121,-116,-110,-103,-94,-85,-75,-64,-52,-39,-26,-13
  1783. },
  1784.            cosinus[] = { /* cosinus-Tabelle */
  1785.   127,126,124,121,116,110,103,94,85,75,64,52,39,26,13,
  1786.   0,-13,-26,-39,-52,-64,-75,-85,-94,-103,-110,-116,-121,-124,-126,
  1787.   -127,-126,-124,-121,-116,-110,-103,-94,-85,-75,-64,-52,-39,-26,-13,
  1788.   0,13,26,39,52,64,75,85,94,103,110,116,121,124,126
  1789. };
  1790.  
  1791. CONST BYTE srect[] = { /* Für rechteckiges Zifferblatt */
  1792.   0,13,27,41,57,73,92,111,124,127,127,127,127,127,127,
  1793.   127,127,127,127,127,127,127,124,111,92,73,57,41,27,13,
  1794.   0,-13,-27,-41,-57,-73,-92,-111,-124,-127,-127,-127,-127,-127,-127,
  1795.   -127,-127,-127,-127,-127,-127,-127,-124,-111,-92,-73,-57,-41,-27,-13
  1796. },
  1797.            crect[] = {
  1798.   127,127,127,127,127,127,127,124,111,92,73,57,41,27,13,
  1799.   0,-13,-27,-41,-57,-73,-92,-111,-124,-127,-127,-127,-127,-127,-127,
  1800.   -127,-127,-127,-127,-127,-127,-127,-124,-111,-92,-73,-57,-41,-27,-13,
  1801.   0,13,27,41,57,73,92,111,124,127,127,127,127,127,127
  1802. };
  1803.  
  1804. CONST UBYTE pent[] = { /* Pen-Tabelle f. Zifferblatt */
  1805.   6,8,8,7,8,8,7,8,8,7,8,8
  1806. };
  1807.  
  1808. CONST BYTE dx1[] = { /* Daten für Zifferblatt */
  1809.   -2, 2, 1,-2, 1, 2,-2,-2,-1,-2,-1,-2
  1810. },
  1811.            dy1[] = {
  1812.   -4,-1,-2,-2, 2, 1,-2, 1, 2,-2,-2,-1
  1813. },
  1814.            dx2[] = {
  1815.    4,-2, 1, 4, 1,-2, 4, 2,-1, 4,-1, 2
  1816. },
  1817.            dy2[] = {
  1818.    0, 3, 2, 0,-2,-3, 0,-3,-2, 0, 2, 3
  1819. },
  1820.            dx3[] = {
  1821.    0,-2,-3, 0,-3,-2, 0, 2, 3, 0, 3, 2
  1822. },
  1823.            dy3[] = {
  1824.    8,-1, 2, 4,-2, 1, 4, 1,-2, 4, 2,-1
  1825. },
  1826.            dx4[] = {
  1827.   -4, 2,-1,-4,-1, 2,-4,-2, 1,-4, 1,-2
  1828. },
  1829.            dy4[] = {
  1830.    0,-3,-2, 0, 2, 3, 0, 3, 2, 0,-2,-3
  1831. };
  1832.  
  1833. VOID ZifferBlatt()
  1834. { struct RastPort *rp = &gb->RPort2;
  1835.   LONG i,a,b,c,x,y,bt,bl;
  1836.  
  1837.   if (gb->BFInfo.BitMap && gb->UseImage)
  1838.   {
  1839.     CopyTiledBitMap(gb->BFInfo.BitMap,
  1840.                     gb->BFInfo.BitMapHeader->bmh_Width,
  1841.                     gb->BFInfo.BitMapHeader->bmh_Height,
  1842.                     &gb->BitMap1,gb->Width2,gb->Height2);
  1843.   }
  1844.   else
  1845.   {
  1846.     BNDRYOFF (rp);
  1847.     SetAPen  (rp,-1);
  1848.     SetAfPt  (rp,&gb->Muster[0][0],-1);
  1849.     RectFill (rp,0,0,gb->Width2-1,gb->Height2-1);
  1850.     SetAfPt  (rp,0,0);
  1851.   }
  1852.  
  1853.   i = gb->Show; a = (i > 1 ? (i == 3 ? 60 : 15) : (i ? 5 : 1));
  1854.   if (i < 4)
  1855.     for (i=0; i<60; i+=a)
  1856.     { x = gb->Width2 /2 + (((gb->Oval ?   sinus[i] : srect[i])*gb->Width2 /300) & gb->xMask);
  1857.       y = gb->Height2/2 - (((gb->Oval ? cosinus[i] : crect[i])*gb->Height2/300) & gb->yMask);
  1858.       if (i%5)
  1859.       { if (i%5==1)
  1860.         { c=gb->Pens[9];
  1861.           SetAPen(rp,c);
  1862.           SetOPen(rp,c);
  1863.         }
  1864.         AreaMove (rp,x+gb->Width2/200,y);
  1865.         AreaDraw (rp,x,y+gb->Height2/200);
  1866.         AreaDraw (rp,x-gb->Width2/200,y);
  1867.         AreaDraw (rp,x,y-gb->Height2/200);
  1868.         AreaEnd  (rp);
  1869.       }
  1870.       else
  1871.       {
  1872.         b=i/5;
  1873.         c=gb->Pens[pent[b]];
  1874.         SetAPen(rp,c);
  1875.         SetOPen(rp,c);
  1876.         AreaMove (rp,x+=gb->Width2*dx1[b]/100,y+=gb->Height2*dy1[b]/100);
  1877.         AreaDraw (rp,x+=gb->Width2*dx2[b]/100,y+=gb->Height2*dy2[b]/100);
  1878.         AreaDraw (rp,x+=gb->Width2*dx3[b]/100,y+=gb->Height2*dy3[b]/100);
  1879.         AreaDraw (rp,x+=gb->Width2*dx4[b]/100,y+=gb->Height2*dy4[b]/100);
  1880.         AreaEnd  (rp);
  1881.       }
  1882.     }
  1883.   if (gb->Shadow)
  1884.   { Zeiger(gb->Std,440,1,gb->Pens[5],gb->Pens[5]);
  1885.     Zeiger(gb->Min,300,1,gb->Pens[5],gb->Pens[5]); }
  1886.   Zeiger(gb->Std,440,0,gb->Pens[3],gb->Pens[4]);
  1887.   Zeiger(gb->Min,300,0,gb->Pens[1],gb->Pens[2]);
  1888.  
  1889.   bl = gb->BoLeft;
  1890.   gb->ReDrawx1 = bl; gb->ReDrawx2 = bl + gb->Width2 -1;
  1891.   bt = gb->BoTop;
  1892.   gb->ReDrawy1 = bt; gb->ReDrawy2 = bt + gb->Height2-1;
  1893. }
  1894.  
  1895. /*
  1896. ** create hands
  1897. */
  1898.  
  1899. CONST LONG HandWidth[] = {
  1900.   4000,3250,2500,1750,1000
  1901. };
  1902.  
  1903. VOID Zeiger(ULONG winkel,LONG lfactor,LONG offset,LONG apen,LONG open)
  1904. { struct RastPort *rp;
  1905.   LONG x0,y0,x1,y1,x2,y2,tmp;
  1906.  
  1907.   tmp = gb->Width2;
  1908.   x2 = sinus  [winkel]*tmp/lfactor;
  1909.   x1 = cosinus[winkel]*tmp/HandWidth[gb->HandWidth];
  1910.   x0 = tmp/2 + (offset ? gb->xOffset : 0);
  1911.  
  1912.   tmp = gb->Height2;
  1913.   y2 = cosinus[winkel]*tmp/lfactor;
  1914.   y1 = sinus  [winkel]*tmp/HandWidth[gb->HandWidth];
  1915.   y0 = tmp/2 + (offset ? gb->yOffset : 0);
  1916.  
  1917.   rp = &gb->RPort2;
  1918.  
  1919.   SetAPen(rp,apen);
  1920.   SetOPen(rp,open);
  1921.  
  1922.   switch (gb->HandType)
  1923.   { case 0:
  1924.       SetAPen(rp,open);
  1925.       Move (rp,x0,y0);
  1926.       Draw (rp,x0+x2,y0-y2);
  1927.       if (gb->xDouble)
  1928.       { Move (rp,1+x0,y0);
  1929.         Draw (rp,1+x0+x2,y0-y2); }
  1930.       if (gb->yDouble)
  1931.       { Move (rp,x0,1+y0);
  1932.         Draw (rp,x0+x2,1+y0-y2); }
  1933.       break;
  1934.     case 1:
  1935.       AreaMove (rp,x0+x2     ,y0-y2     );
  1936.       AreaDraw (rp,x0+x1-x2/4,y0+y1+y2/4);
  1937.       AreaDraw (rp,x0-x1-x2/4,y0-y1+y2/4);
  1938.       AreaEnd  (rp);
  1939.       break;
  1940.     case 2:
  1941.       AreaMove (rp,x0+x2  ,y0-y2  );
  1942.       AreaDraw (rp,x0+x1  ,y0+y1  );
  1943.       AreaDraw (rp,x0-x2/4,y0+y2/4);
  1944.       AreaDraw (rp,x0-x1  ,y0-y1  );
  1945.       AreaEnd  (rp);
  1946.       break;
  1947.     case 3:
  1948.       AreaMove (rp,x0+=x2-x1/2,y0-=y2+y1/2);
  1949.       AreaDraw (rp,x0+=x1     ,y0+=y1     );
  1950.       AreaDraw (rp,x0-=x2*5/4 ,y0+=y2*5/4 );
  1951.       AreaDraw (rp,x0-=x1     ,y0-=y1     );
  1952.       AreaEnd  (rp);
  1953.       break;
  1954.   }
  1955. }
  1956.  
  1957. /***************************************************************************/
  1958. /*                                                                         */
  1959. /* display the clock (blit from the `hidden' window to real one)           */
  1960. /*                                                                         */
  1961. /***************************************************************************/
  1962.  
  1963. VOID Zeichnen()
  1964. { struct RastPort *rp = gb->RPort1;
  1965.   LONG tmp,x1,y1,x2,y2;
  1966.  
  1967.   BltBitMapRastPort(&gb->BitMap1,gb->ReDrawx1-gb->BoLeft,gb->ReDrawy1-gb->BoTop,
  1968.                     rp,gb->ReDrawx1,gb->ReDrawy1,gb->ReDrawx2-gb->ReDrawx1+1,
  1969.                     gb->ReDrawy2-gb->ReDrawy1+1,0xc0);
  1970.   if (gb->Seconds)
  1971.   {
  1972.     x1 = gb->Width/2;
  1973.     x2 = x1+sinus[gb->Sec]*gb->Width2/300;
  1974.     y1 = gb->Height/2;
  1975.     y2 = y1-cosinus[gb->Sec]*gb->Height2/300;
  1976.  
  1977.     Move(rp,x1,y1);
  1978.     Draw(rp,x2,y2);
  1979.  
  1980.     if (gb->xDouble)
  1981.     { Move(rp,x1+1,y1);
  1982.       Draw(rp,x2+1,y2); }
  1983.  
  1984.     if (gb->yDouble)
  1985.     { Move(rp,x1,y1+1);
  1986.       Draw(rp,x2,y2+1); }
  1987.  
  1988.     if (x1 > x2)
  1989.     { tmp=x1; x1=x2; x2=tmp; }
  1990.     if (gb->xDouble)
  1991.       x2++;
  1992.     gb->ReDrawx1 = x1; gb->ReDrawx2 = x2;
  1993.  
  1994.     if (y1 > y2)
  1995.     { tmp=y1; y1=y2; y2=tmp; }
  1996.     if (gb->yDouble)
  1997.       y2++;
  1998.     gb->ReDrawy1 = y1; gb->ReDrawy2 = y2;
  1999.   }
  2000. }
  2001.  
  2002. /***************************************************************************/
  2003. /*                                                                         */
  2004. /* initialize background pattern mask                                      */
  2005. /*                                                                         */
  2006. /***************************************************************************/
  2007.  
  2008. VOID SetPattern()
  2009. { LONG i,a,b,c,d;
  2010.   UBYTE *p1;
  2011.   UWORD *p2;
  2012.  
  2013.   p1=&gb->Must[0]; a=*p1++; b=*p1++; c=*p1++; d=*p1;
  2014.  
  2015.   if (a==b && c==d) /* nur horizontale Streifen */
  2016.     gb->xMask = -1;
  2017.   else
  2018.     gb->xMask = -2;
  2019.  
  2020.   if (a==c && b==d) /* nur vertikale Streifen */
  2021.     gb->yMask = -1;
  2022.   else
  2023.     gb->yMask = -2;
  2024.  
  2025.   for (p2=&gb->Muster[0][0],i=0; i<8; i++)
  2026.   { *p2=(a&1<<i?0x5555:0)|(b&1<<i?0xaaaa:0); p2++;
  2027.     *p2=(c&1<<i?0x5555:0)|(d&1<<i?0xaaaa:0); p2++; }
  2028. }
  2029.  
  2030. /***************************************************************************/
  2031. /*                                                                         */
  2032. /* save current settings to the programs icon                              */
  2033. /*                                                                         */
  2034. /***************************************************************************/
  2035.  
  2036. enum {TT_TOP=0,TT_LEFT,TT_WIDTH,TT_HEIGHT,TT_SHOWFACE,TT_HANDTYPE,TT_HANDWIDTH,
  2037.       TT_BORDERTYPE,TT_CHIME,TT_SECONDS,TT_OVAL,TT_SHADOW,TT_CLOSEGAD,TT_USEIMAGE,
  2038.       TT_DRAWPENS,TT_PATTERN};
  2039.  
  2040. CONST STRPTR ToolTypes[] = {
  2041.   "TOP","LEFT","WIDTH","HEIGHT","SHOWFACE","HANDTYPE","HANDWIDTH","BORDERTYPE",
  2042.   "CHIME","SECONDS","OVAL","SHADOW","CLOSEGAD","USEIMAGE","DRAWPENS","PATTERN"
  2043. };
  2044.  
  2045. #define TTCOUNT (sizeof(ToolTypes)/sizeof(ToolTypes[0]))
  2046.  
  2047. VOID SaveSettings()
  2048. { struct DiskObject *dobj;
  2049.   BPTR old_cd;
  2050.  
  2051.   old_cd = CurrentDir(gb->ProgArg.wa_Lock);
  2052.  
  2053.   if ((dobj=GetDiskObjectNew(gb->ProgArg.wa_Name)) != NULL) /* Tooltypes einlesen */
  2054.   {
  2055.     UBYTE **tt,*t,*tbuf,*tbuf1;
  2056.     char **tmp,*p,**p1,**p2;
  2057.     LONG arg,i;
  2058.  
  2059.     p1=dobj->do_ToolTypes; p2=p1; do {} while(*p2++);
  2060.  
  2061.     if ((tbuf=AllocVec(((STRPTR)p2-(STRPTR)p1)+sizeof(ToolTypes)+40*TTCOUNT,MEMF_ANY)))
  2062.     {
  2063.       tt=(UBYTE **)(tbuf+40*TTCOUNT);
  2064.  
  2065.       p1=dobj->do_ToolTypes; p2=(char **)tt; do {} while((*p2++=*p1++));
  2066.  
  2067.       for (i=0;i<TTCOUNT;i++) /* eigene Tooltypes entfernen */
  2068.       { if (FindToolType(tt,t=GetToolType(i)))
  2069.         { p2=(char **)tt; do {} while(*++p2 && FindToolType((UBYTE **)p2,t));
  2070.           do { p=*p2++; } while((p2[-2]=p));
  2071.         }
  2072.       }
  2073.  
  2074.       /* Tooltypes zählen */
  2075.       p1=(char **)tt; do {} while(*p1++); --p1; tbuf1=tbuf;
  2076.  
  2077.       *p1++=tbuf1;
  2078.       tbuf1=SetToolType(tbuf1,"%s=%ld",TT_TOP,gb->MainWin->TopEdge);
  2079.  
  2080.       *p1++=tbuf1;
  2081.       tbuf1=SetToolType(tbuf1,"%s=%ld",TT_LEFT,gb->MainWin->LeftEdge);
  2082.  
  2083.       *p1++=tbuf1;
  2084.       tbuf1=SetToolType(tbuf1,"%s=%ld",TT_WIDTH,gb->Width);
  2085.  
  2086.       *p1++=tbuf1;
  2087.       tbuf1=SetToolType(tbuf1,"%s=%ld",TT_HEIGHT,gb->Height);
  2088.  
  2089.       *p1++=tbuf1;
  2090.       tbuf1=SetToolType(tbuf1,"%s=%ld",TT_SHOWFACE,gb->Show);
  2091.  
  2092.       *p1++=tbuf1;
  2093.       tbuf1=SetToolType(tbuf1,"%s=%ld",TT_HANDTYPE,gb->HandType);
  2094.  
  2095.       *p1++=tbuf1;
  2096.       tbuf1=SetToolType(tbuf1,"%s=%ld",TT_HANDWIDTH,gb->HandWidth);
  2097.  
  2098.       *p1++=tbuf1;
  2099.       arg = gb->BorderCount + (gb->HiRes ? 4 : 0) + (gb->Interlace ? 8 : 0);
  2100.       tbuf1=SetToolType(tbuf1,"%s=%ld",TT_BORDERTYPE,arg);
  2101.  
  2102.       *p1++=tbuf1;
  2103.       arg = gb->Chime + (gb->SmartHour ? 4 : 0);
  2104.       tbuf1=SetToolType(tbuf1,"%s=%ld",TT_CHIME,arg);
  2105.  
  2106.       if (gb->Seconds)
  2107.         { *p1++=tbuf1; tbuf1=SetToolType(tbuf1,"%s",TT_SECONDS); }
  2108.  
  2109.       if (gb->Oval)
  2110.         { *p1++=tbuf1; tbuf1=SetToolType(tbuf1,"%s",TT_OVAL); }
  2111.  
  2112.       if (gb->Shadow)
  2113.         { *p1++=tbuf1; tbuf1=SetToolType(tbuf1,"%s",TT_SHADOW); }
  2114.  
  2115.       if (gb->CloseGad)
  2116.         { *p1++=tbuf1; tbuf1=SetToolType(tbuf1,"%s",TT_CLOSEGAD); }
  2117.  
  2118.       if (gb->UseImage)
  2119.         { *p1++=tbuf1; tbuf1=SetToolType(tbuf1,"%s",TT_USEIMAGE); }
  2120.  
  2121.       *p1++=tbuf1;
  2122.       tbuf1=SetToolType(tbuf1,"%s=x",TT_DRAWPENS); tbuf1=SetStr(tbuf1,&gb->Pens[0],14);
  2123.  
  2124.       *p1++=tbuf1;
  2125.       tbuf1=SetToolType(tbuf1,"%s=x",TT_PATTERN); tbuf1=SetStr(tbuf1,&gb->Must[0],4);
  2126.  
  2127.       *p1=NULL;
  2128.  
  2129.       tmp=dobj->do_ToolTypes;
  2130.       dobj->do_ToolTypes=(char **)tt;
  2131.       PutDiskObject(gb->ProgArg.wa_Name,dobj);
  2132.       dobj->do_ToolTypes=tmp;
  2133.  
  2134.       FreeVec(tbuf);
  2135.     }
  2136.     FreeDiskObject(dobj);
  2137.   }
  2138.   CurrentDir(old_cd);
  2139. }
  2140.  
  2141. /*
  2142. ** make a tooltype string
  2143. */
  2144.  
  2145. CONST ULONG tricky=0x16c04e75; /* move.b d0,(a3)+ ; rts */
  2146.  
  2147. STRPTR SetToolType(STRPTR buf,STRPTR fmt,LONG num,...)
  2148. {
  2149.   ((STRPTR *)&num)[0] = GetToolType(num);
  2150.   RawDoFmt(fmt,(APTR)&num,(void (*)())&tricky,buf);
  2151.   return (buf+=strlen(buf)+1);
  2152. }
  2153.  
  2154. /*
  2155. ** get a tooltype name
  2156. */
  2157.  
  2158. STRPTR GetToolType(LONG num)
  2159. {
  2160.   return (STRPTR)ToolTypes[num];
  2161. }
  2162.  
  2163. /*
  2164. ** make an ascii pen-string
  2165. */
  2166.  
  2167. STRPTR SetStr(STRPTR dst,STRPTR src,LONG cnt)
  2168. {
  2169.   --dst;
  2170.   do
  2171.   { *dst++=DtoX(*src>>4);
  2172.     *dst++=DtoX(*src++&0xf);
  2173.   } while (--cnt);
  2174.   *dst++='\0'; return dst;
  2175. }
  2176.  
  2177. LONG DtoX(LONG a)
  2178. { if ((a+='0')>('9'))
  2179.     a+=7;
  2180.   return(a);
  2181. }
  2182.  
  2183. /***************************************************************************/
  2184. /*                                                                         */
  2185. /* audio stuff                                                             */
  2186. /*                                                                         */
  2187. /***************************************************************************/
  2188.  
  2189. CONST UWORD AlarmTune[] = {
  2190.   800,800,800,800,800,800,800,1600,
  2191.   800,800,800,800,800,800,800,1600,
  2192.   800,800,800,800,800,800,800,1600,
  2193.   800,800,800,800,800,800,800,1600,
  2194.   800,800,800,800,800,800,800,4,0
  2195. };
  2196.  
  2197. CONST UWORD HourTune[] = {
  2198.   800,1600,800,1600,800,1600,800,1600,
  2199.   800,1600,800,1600,800,1600,800,1600,
  2200.   800,1600,800,1600,800,1600,800,4,0
  2201. };
  2202.  
  2203. CONST UWORD QuarterTune[] = {
  2204.   400,400,400,400,400,4,0
  2205. };
  2206.  
  2207. VOID TestIfAlarm()
  2208. { CONST UWORD *tune;
  2209.   ULONG st2;
  2210.   LONG mi2,i;
  2211.  
  2212.   st2=gb->Std; mi2 = gb->Min;
  2213.   if (!(st2/=5))
  2214.     st2=12;
  2215.   tune = AlarmTune;
  2216.   if (!gb->Alarm || mi2!=gb->AlMin || st2!=gb->AlStd)
  2217.   { if (!gb->Chime)
  2218.       return;
  2219.     if (!mi2)
  2220.     {
  2221.       tune = HourTune; i=22; if (gb->SmartHour) i=24-st2;
  2222.     }
  2223.     else
  2224.     { if (gb->Chime != 2)
  2225.         return;
  2226.       tune = QuarterTune;
  2227.       for(i=6;;)
  2228.        { i-=2;
  2229.          if ((mi2-=15)<0)
  2230.            return;
  2231.          if (mi2==0)
  2232.            break;
  2233.        }
  2234.     }
  2235.     tune = &tune[i];
  2236.   }
  2237.   StartTune(tune);
  2238. }
  2239.  
  2240. /*
  2241. ** allocate audio channels and initiate the sound
  2242. */
  2243.  
  2244. CONST UBYTE ChannelMap[] = { 1,2,4,8 }; /* Sound Channel Allocation Map */
  2245.  
  2246. VOID StartTune(CONST UWORD *tune)
  2247. { struct IOAudio *io;
  2248.  
  2249.   if (!gb->SoundOn)
  2250.   {
  2251.     io = gb->AudioIO[0];
  2252.     io->ioa_Request.io_Command = ADCMD_ALLOCATE;
  2253.     io->ioa_Request.io_Message.mn_Node.ln_Pri = 90; /* ALARM-Level */
  2254.     io->ioa_Request.io_Flags   = ADIOF_NOWAIT;
  2255.     io->ioa_Data               = (UBYTE *)&ChannelMap[0];
  2256.     io->ioa_Length             = sizeof(ChannelMap);
  2257.     BeginIO(&io->ioa_Request);
  2258.     if (!WaitIO(&io->ioa_Request))
  2259.     {
  2260.       gb->SoundOn = -1;
  2261.       if (!(ciaa.ciapra & CIAF_LED))
  2262.       {
  2263.         ciaa.ciapra |= CIAF_LED; gb->Filter = -1;
  2264.       }
  2265.       CopyMemQuick(io,gb->AudioIO[1],sizeof(struct IOAudio));
  2266.       gb->PlayTune = (UWORD *)tune;
  2267.       PlayNote();
  2268.       PlayNote();
  2269.     }
  2270.   }
  2271. }
  2272.  
  2273. /*
  2274. ** beep, beep, ...
  2275. */
  2276.  
  2277. VOID PlayNote()
  2278. { struct IOAudio *io;
  2279.   LONG old,new;
  2280.   BYTE *sent = &gb->AudioSent[0];
  2281.  
  2282.   old = gb->RequestNr;
  2283.   new = !old;
  2284.   gb->RequestNr = new;
  2285.  
  2286.   sent[old] =  0;
  2287.   if (!*gb->PlayTune)
  2288.   { if (!sent[new]) /* Anderer Request auch zurück ? */
  2289.       EndTune(); return; }
  2290.   sent[old] = -1;   /* Merken */
  2291.   io = gb->AudioIO[old];
  2292.   io->ioa_Request.io_Command = CMD_WRITE;
  2293.   io->ioa_Request.io_Flags   = ADIOF_PERVOL;
  2294.   io->ioa_Data               = (UBYTE *)&((ULONG *)gb->WaveForm)[old];
  2295.   io->ioa_Length             = 4;
  2296.   io->ioa_Period             = 500; /* ekliger Piepton */
  2297.   io->ioa_Volume             = 64;
  2298.   io->ioa_Cycles             = *(gb->PlayTune)++;
  2299.   BeginIO(&io->ioa_Request);
  2300. }
  2301.  
  2302. /*
  2303. ** end audio output
  2304. */
  2305.  
  2306. VOID EndTune()
  2307. { struct IOAudio *ioreq = gb->AudioIO[0];
  2308.  
  2309.   ioreq->ioa_Request.io_Command=ADCMD_FREE;
  2310.   DoIO(&ioreq->ioa_Request);
  2311.   if (gb->Filter)
  2312.   {
  2313.     ciaa.ciapra &= ~CIAF_LED; gb->Filter = 0;
  2314.   }
  2315.   gb->SoundOn = 0;
  2316. }
  2317.  
  2318. /***************************************************************************/
  2319. /*                                                                         */
  2320. /* create a new window and its gadgets                                     */
  2321. /*                                                                         */
  2322. /***************************************************************************/
  2323.  
  2324. CONST struct TextAttr Topaz = {
  2325.   "topaz.font",8,FS_NORMAL,FPF_ROMFONT
  2326. };
  2327.  
  2328. VOID CreateRequest(struct WinGad *wg,struct wInfo *wi,struct TagItem **tagptr)
  2329. { struct Gadget *context;
  2330.  
  2331.   if ((context=CreateContext(&wg->Gad)) != NULL)
  2332.   {
  2333.     struct NewWindow *nw = &gb->NewWindowBuf;
  2334.     struct Window *win;
  2335.     struct gInfo *gi;
  2336.     UWORD cnt;
  2337.  
  2338.     nw->LeftEdge    = 100;
  2339.     nw->TopEdge     = 100;
  2340.     nw->Width       = 0;
  2341.     nw->Height      = 0;
  2342.     nw->Flags       = WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_ACTIVATE|WFLG_RMBTRAP;
  2343.     nw->FirstGadget = wg->Gad;
  2344.     nw->Title       = GetCatalogString(wi->textnr);
  2345.  
  2346.     gb->NewGad.ng_GadgetID = 0; cnt = wi->gadcnt; gi = &wi->gi[0];
  2347.     do
  2348.     { struct NewGadget *ng = &gb->NewGad;
  2349.       struct Screen *scr = gb->MainWin->WScreen;
  2350.       ULONG num;
  2351.  
  2352.       ng->ng_LeftEdge   = gi->left + scr->WBorLeft;
  2353.       ng->ng_TopEdge    = gi->top  + scr->WBorLeft + scr->RastPort.TxHeight;
  2354.       ng->ng_Width      = gi->width;
  2355.       ng->ng_Height     = gi->height;
  2356.       if ((num=gi->textnr))
  2357.         num = (ULONG)GetCatalogString(num);
  2358.       ng->ng_GadgetText = (STRPTR)num;
  2359.       ng->ng_TextAttr   = (struct TextAttr *)&Topaz;
  2360.       ng->ng_GadgetID++;
  2361.       ng->ng_VisualInfo = gb->VisualInfo;
  2362.  
  2363.       if ((context=CreateGadgetA(gi->kind,context,ng,tagptr[0])) == NULL)
  2364.       {
  2365.         FreeGadgets(wg->Gad); wg->Gad = NULL; return;
  2366.       }
  2367.  
  2368.       gi++; tagptr++;
  2369.     } while(--cnt);
  2370.  
  2371.     if ((wg->Win=(win=OpenWindowShared(&gb->NewWindowBuf,&WindowTags[0],wi->idcmp))) != NULL)
  2372.     {
  2373.       SetWindowTitles(win,(UBYTE *)-1L,PROGNAME); GT_RefreshWindow(win,NULL);
  2374.     }
  2375.     else
  2376.     {
  2377.       FreeGadgets(wg->Gad); wg->Gad = NULL;
  2378.     }
  2379.   }
  2380. }
  2381.  
  2382. /***************************************************************************/
  2383. /*                                                                         */
  2384. /* open a window for shared IDCMP                                          */
  2385. /*                                                                         */
  2386. /***************************************************************************/
  2387.  
  2388. struct Window *OpenWindowShared(struct NewWindow *nw,CONST struct TagItem *tl,ULONG idcmp)
  2389. { struct Window *win;
  2390.  
  2391.   if ((win=OpenWindowTagList(nw,(struct TagItem *)tl)) != NULL)
  2392.   {
  2393.     win->UserPort = gb->WindowPort;
  2394.     if (!ModifyIDCMP(win,idcmp))
  2395.     {
  2396.       CloseWindowSafely(win); win=NULL;
  2397.     }
  2398.   }
  2399.   return win;
  2400. }
  2401.  
  2402. /***************************************************************************/
  2403. /*                                                                         */
  2404. /* get localized string                                                    */
  2405. /*                                                                         */
  2406. /***************************************************************************/
  2407.  
  2408. CONST STRPTR LocStrings[] = {
  2409.   /* MSG_PROJECT     */ "Project",
  2410.   /* MSG_ABOUT       */ "About",
  2411.   /* MSG_ABOUTKEY    */ "?",
  2412.   /* MSG_QUIT        */ "Quit",
  2413.   /* MSG_QUITKEY     */ "Q",
  2414.   /* MSG_SETTINGS    */ "Settings",
  2415.   /* MSG_SECONDS     */ "Seconds",
  2416.   /* MSG_OVAL        */ "Oval",
  2417.   /* MSG_SHOW        */ "show",
  2418.   /* MSG_MINUTES     */ "Minutes",
  2419.   /* MSG_HOURS       */ "Hours",
  2420.   /* MSG_QUARTER     */ "Quarter",
  2421.   /* MSG_ONE         */ "One",
  2422.   /* MSG_NONE        */ "None",
  2423.   /* MSG_HANDS       */ "Hands",
  2424.   /* MSG_LINE        */ "Line",
  2425.   /* MSG_TRIANGLE    */ "Triangle",
  2426.   /* MSG_RHOMBUS     */ "Rhombus",
  2427.   /* MSG_RECTANGLE   */ "Rectangle",
  2428.   /* MSG_VERYTHIN    */ "Very Thin",
  2429.   /* MSG_THIN        */ "Thin",
  2430.   /* MSG_NORMAL      */ "Normal",
  2431.   /* MSG_THICK       */ "Thick",
  2432.   /* MSG_VERYTHICK   */ "Very Thick",
  2433.   /* MSG_SHADOW      */ "Shadow",
  2434.   /* MSG_BORDER      */ "Border",
  2435.   /* MSG_SINGLE      */ "Single",
  2436.   /* MSG_DOUBLE      */ "Double",
  2437.   /* MSG_HIRES       */ "HiRes",
  2438.   /* MSG_INTERLACE   */ "Interlace",
  2439.   /* MSG_CHIME       */ "Chime",
  2440.   /* MSG_SMART       */ "Smart",
  2441.   /* MSG_ALARM       */ "Alarm",
  2442.   /* MSG_SET         */ "Set",
  2443.   /* MSG_ON          */ "On",
  2444.   /* MSG_USEIMAGE    */ "Use Image",
  2445.   /* MSG_CLOSEGAD    */ "Close Gadget",
  2446.   /* MSG_SAVESETTING */ "Save Settings",
  2447.   /* MSG_SAVEKEY     */ "S",
  2448.   /* MSG_COLORS      */ "Colors",
  2449.   /* MSG_MINAPEN     */ "Min. APen",
  2450.   /* MSG_MINOPEN     */ "Min. OPen",
  2451.   /* MSG_HOURAPEN    */ "Hour Apen",
  2452.   /* MSG_HOUROPEN    */ "Hour Open",
  2453.   /* MSG_STR12       */ "12",
  2454.   /* MSG_BORDER0     */ "Border 0",
  2455.   /* MSG_BORDER1     */ "Border 1",
  2456.   /* MSG_BORDER2     */ "Border 2",
  2457.   /* MSG_BORDER3     */ "Border 3",
  2458.   /* MSG_PATTERN     */ "Pattern",
  2459.   /* MSG_COLOR0      */ "Color 0",
  2460.   /* MSG_COLOR1      */ "Color 1",
  2461.   /* MSG_COLOR2      */ "Color 2",
  2462.   /* MSG_COLOR3      */ "Color 3",
  2463.   /* MSG_DESCRIPTION */ "a really nice clock !",
  2464.   /* MSG_CHOOSE      */ "Choose one:",
  2465.   /* MSG_USE         */ "Use",
  2466.   /* MSG_CANCEL      */ "Cancel"
  2467. };
  2468.  
  2469. STRPTR GetCatalogString(LONG strnum)
  2470. { struct Catalog *cat;
  2471.   STRPTR loc;
  2472.  
  2473.   loc = LocStrings[strnum];
  2474.   if ((cat=gb->Catalog) != NULL)
  2475.     loc = GetCatalogStr(cat,strnum,loc);
  2476.   return loc;
  2477. }
  2478.  
  2479. /***************************************************************************/
  2480. /*                                                                         */
  2481. /* duplicate a bitmap (based on the work of P.Carette + W.Dörwald)         */
  2482. /*                                                                         */
  2483. /***************************************************************************/
  2484.  
  2485. VOID CopyTiledBitMap(struct BitMap *Src,LONG SrcSizeX,LONG SrcSizeY,struct BitMap *Dst,LONG DstSizeX,LONG DstSizeY)
  2486. { LONG Pos;  /* used as starting position in the "exponential" blit */
  2487.   LONG Size; /* used as bitmap size in the "exponential" blit       */
  2488.  
  2489.   /* blit the first piece of the tile */
  2490.   blt_bitmap(Src,0,0,Dst,0,0,MIN(SrcSizeX,DstSizeX),MIN(SrcSizeY,DstSizeY),0xC0,-1,NULL);
  2491.  
  2492.   /* this loop generates the first row of the tiles */
  2493.   for (Pos = SrcSizeX,Size = MIN(SrcSizeX,DstSizeX-Pos);Pos<DstSizeX;)
  2494.   {
  2495.     blt_bitmap(Dst,0,0,Dst,Pos,0,Size,MIN(SrcSizeY,DstSizeY),0xC0,-1,NULL);
  2496.     Pos += Size;
  2497.     Size = MIN(Size<<1,DstSizeX-Pos);
  2498.   }
  2499.  
  2500.   /* this loop blit the first row down several times to fill the whole dest rect */
  2501.   for (Pos = SrcSizeY,Size = MIN(SrcSizeY,DstSizeY-Pos);Pos<DstSizeY;)
  2502.   {
  2503.     blt_bitmap(Dst,0,0,Dst,0,Pos,DstSizeX,Size,0xC0,-1,NULL);
  2504.     Pos += Size;
  2505.     Size = MIN(Size<<1,DstSizeY-Pos);
  2506.   }
  2507. }
  2508.  
  2509. /***************************************************************************/
  2510. /*                                                                         */
  2511. /* replacement functions                                                   */
  2512. /*                                                                         */
  2513. /***************************************************************************/
  2514.  
  2515. Object *new_dt_object(APTR name, ULONG data, ...)
  2516. {
  2517.   return NewDTObjectA(name,(struct TagItem *)&data);
  2518. }
  2519.  
  2520. ULONG get_dt_attrs(Object *obj, ULONG data, ...)
  2521. {
  2522.   return GetDTAttrsA(obj,(struct TagItem *)&data);
  2523. }
  2524.  
  2525. LONG blt_bitmap(struct BitMap *src,LONG xsrc,LONG ysrc,struct BitMap *dst,
  2526.                 LONG xdst,LONG ydst,LONG xsize,LONG ysize,ULONG minterm,
  2527.                 ULONG mask,PLANEPTR tempA)
  2528. {
  2529.   return BltBitMap(src,xsrc,ysrc,dst,xdst,ydst,xsize,ysize,minterm,mask,tempA);
  2530. }
  2531.  
  2532. /***************************************************************************/
  2533. /*                                                                         */
  2534. /* The End                                                                 */
  2535. /*                                                                         */
  2536. /***************************************************************************/
  2537.